Files
makemd/docs/RULES/typescript.md
wurenzhi 2b86715c09 refactor: 优化代码结构并修复类型问题
- 移除未使用的TabPane组件
- 修复类型定义和导入方式
- 优化mock数据源的环境变量判断逻辑
- 更新文档结构并归档旧文件
- 添加新的UI组件和Memo组件
- 调整API路径和响应处理
2026-03-23 12:41:35 +08:00

4.4 KiB
Raw Blame History

TypeScript规则

入口: _index.md


1. 核心原则

1.1 禁止any

// ❌ 禁止
function process(data: any) { ... }
const result: any = fetchData();

// ✅ 正确
function process(data: unknown) {
  if (typeof data === 'string') {
    // 类型收窄后使用
  }
}

interface FetchResult {
  id: string;
  name: string;
}
const result: FetchResult = fetchData();

1.2 函数必须声明返回类型

// ❌ 禁止
function getProduct(id: string) {
  return db('cf_product').where({ id }).first();
}

// ✅ 正确
interface Product {
  id: string;
  name: string;
  price: number;
}

async function getProduct(id: string): Promise<Product | null> {
  return db('cf_product').where({ id }).first();
}

1.3 API必须定义类型

// ❌ 禁止
router.post('/api/v1/products', async (ctx) => {
  const body = ctx.request.body; // any
  // ...
});

// ✅ 正确
interface CreateProductRequest {
  name: string;
  price: number;
  platform: string;
}

interface CreateProductResponse {
  success: boolean;
  data: Product;
}

router.post('/api/v1/products', async (ctx) => {
  const body = ctx.request.body as CreateProductRequest;
  // ...
});

2. 类型定义规范

2.1 Schema驱动

类型必须从 Schemazod推导禁止手动定义

// ❌ 禁止:手动定义类型
interface Product {
  id: string;
  name: string;
  price: number;
}

// ✅ 正确从Schema推导
import { z } from 'zod';

const ProductSchema = z.object({
  id: z.string(),
  name: z.string(),
  price: z.number(),
});

type Product = z.infer<typeof ProductSchema>;

2.2 统一类型中心

所有类型只从 /types 目录导入:

// ❌ 禁止:各模块重复定义
// services/ProductService.ts
interface Product { ... }

// ✅ 正确:从类型中心导入
import { Product, CreateProductRequest } from '@/types';

2.3 类型边界分层

API 返回数据 → Schema 验证 → DTO 转换 → Domain 模型
// 1. API返回不可信
const apiData = await fetchProduct();

// 2. Schema验证
const validated = ProductSchema.parse(apiData);

// 3. DTO转换
const dto: ProductDTO = {
  id: validated.id,
  name: validated.name,
  price: validated.price,
};

// 4. Domain模型
const domain: Product = Product.fromDTO(dto);

3. 编译检查

3.1 强制规则

规则 说明
编译错误 = 构建失败 TypeScript 编译错误必须阻断 CI/CD
提交前检查 必须通过 tsc --noEmit 检查
ESLint 强制 必须通过 @typescript-eslint 规则检查

3.2 禁止行为

// ❌ 禁止:忽略错误
// @ts-ignore
const result = someFunction();

// ❌ 禁止:禁用检查
// @ts-nocheck
function process() { ... }

// ❌ 禁止将类型改为any来"解决"错误
const data: any = fetchData();

4. 类型转换

4.1 类型守卫

// ✅ 正确:使用类型守卫
function isProduct(data: unknown): data is Product {
  return (
    typeof data === 'object' &&
    data !== null &&
    'id' in data &&
    'name' in data &&
    'price' in data
  );
}

function process(data: unknown) {
  if (isProduct(data)) {
    // data 类型为 Product
    console.log(data.name);
  }
}

4.2 类型断言

// ❌ 禁止:过度使用断言
const product = data as Product;

// ✅ 正确先用Schema验证
const product = ProductSchema.parse(data);

5. 文件规模限制

类型 限制
单文件 ≤ 1500 行
单函数 ≤ 120 行
UI组件 ≤ 300 行

6. 命名规范

6.1 文件命名

类型 格式 示例
组件 PascalCase ProductList.tsx
服务 PascalCase ProductService.ts
工具 camelCase formatPrice.ts
类型 camelCase productTypes.ts

6.2 类型命名

// 接口:不加 I 前缀
interface Product { ... }

// 类型别名:描述性名称
type ProductStatus = 'ACTIVE' | 'INACTIVE';

// 泛型:单字母或描述性名称
function getItems<T>(): T[] { ... }
function transform<Input, Output>(data: Input): Output { ... }

7. 检查命令

# 类型检查
npx tsc --noEmit

# 检查错误数量
npx tsc --noEmit 2>&1 | Select-String -Pattern "^src/" | Measure-Object

最后更新: 2026-03-22