| title | TypeScript 编码规范 | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| type | context_aware | |||||||||||
| priority | high | |||||||||||
| description | TypeScript 项目的编码标准和最佳实践 | |||||||||||
| enabled | true | |||||||||||
| tags |
|
|||||||||||
| triggers |
|
- 使用 2 空格缩进
- 行尾不要有空格
- 文件末尾保留一个空行
-
变量和函数: camelCase
const userName = 'John'; function getUserInfo() {}
-
类和接口: PascalCase
class UserManager {} interface UserProfile {}
-
常量: UPPER_SNAKE_CASE
const MAX_RETRY_COUNT = 3; const API_BASE_URL = 'https://api.example.com';
-
类型别名: PascalCase
type UserId = string; type UserCallback = (user: User) => void;
- 字符串优先使用单引号
' - 模板字符串使用反引号
` - 始终使用分号结尾
✅ 推荐:
function greet(name: string): string {
return `Hello, ${name}!`;
}
const add = (a: number, b: number): number => a + b;❌ 不推荐:
function greet(name) {
return `Hello, ${name}!`;
}
const add = (a, b) => a + b;- 优先使用接口定义对象结构
- 使用类型别名定义联合类型、交叉类型等
✅ 推荐:
interface User {
id: string;
name: string;
email: string;
}
type Status = 'pending' | 'active' | 'inactive';
type Result<T> = { success: true; data: T } | { success: false; error: string };尽量避免使用 any 类型,使用更具体的类型或 unknown:
✅ 推荐:
function processData(data: unknown): void {
if (typeof data === 'string') {
console.log(data.toUpperCase());
}
}❌ 不推荐:
function processData(data: any): void {
console.log(data.toUpperCase());
}- 优先使用
const - 需要重新赋值时使用
let - 永远不要使用
var
const MAX_SIZE = 100; // 常量
let counter = 0; // 可变- 优先使用箭头函数(除非需要
this绑定) - 保持函数简短和单一职责
✅ 推荐:
const users = data.map(item => transformUser(item));
class Component {
handleClick = () => {
// 箭头函数自动绑定 this
this.setState({ clicked: true });
};
}使用解构语法简化代码:
// 对象解构
const { name, email } = user;
// 数组解构
const [first, second] = items;
// 函数参数解构
function greet({ name, age }: User) {
console.log(`${name} is ${age} years old`);
}使用现代 TypeScript 特性:
// 可选链
const userName = user?.profile?.name;
// 空值合并
const displayName = userName ?? 'Guest';优先使用 async/await 而非 Promise 链:
✅ 推荐:
async function fetchUserData(userId: string): Promise<User> {
try {
const response = await fetch(`/api/users/${userId}`);
if (!response.ok) {
throw new Error('Failed to fetch user');
}
return await response.json();
} catch (error) {
console.error('Error fetching user:', error);
throw error;
}
}使用类型守卫确保类型安全:
function isUser(obj: unknown): obj is User {
return (
typeof obj === 'object' &&
obj !== null &&
'id' in obj &&
'name' in obj
);
}
if (isUser(data)) {
// TypeScript 知道 data 是 User 类型
console.log(data.name);
}为公共 API 添加 JSDoc 注释:
/**
* 计算两个数的和
* @param a - 第一个数字
* @param b - 第二个数字
* @returns 两数之和
*/
function add(a: number, b: number): number {
return a + b;
}仅在必要时添加注释,解释"为什么"而非"是什么":
// ✅ 好的注释 - 解释原因
// 使用 setTimeout 避免阻塞 UI 线程
setTimeout(() => processLargeData(data), 0);
// ❌ 不好的注释 - 重复代码
// 给 x 加 1
x = x + 1;- 第三方库
- 内部模块
- 相对路径导入
- 类型导入
// 第三方库
import React from 'react';
import { useEffect, useState } from 'react';
// 内部模块
import { apiClient } from '@/api';
import { formatDate } from '@/utils';
// 相对路径
import { UserCard } from './components/UserCard';
import type { User } from './types';优先使用命名导出而非默认导出:
✅ 推荐:
export function formatDate(date: Date): string { }
export class UserManager { }❌ 不推荐(除非组件):
export default function formatDate(date: Date): string { }创建有意义的错误类型:
class ValidationError extends Error {
constructor(
message: string,
public field: string
) {
super(message);
this.name = 'ValidationError';
}
}
throw new ValidationError('Invalid email format', 'email');使用 try-catch 适当处理错误:
try {
const result = await riskyOperation();
return result;
} catch (error) {
if (error instanceof ValidationError) {
// 处理验证错误
showFieldError(error.field, error.message);
} else {
// 处理其他错误
logError(error);
showGenericError();
}
throw error; // 重新抛出或处理
}// 使用 React.memo
export const UserCard = React.memo<UserCardProps>(({ user }) => {
return <div>{user.name}</div>;
});
// 使用 useCallback 和 useMemo
const handleClick = useCallback(() => {
processUser(user);
}, [user]);
const sortedUsers = useMemo(
() => users.sort((a, b) => a.name.localeCompare(b.name)),
[users]
);对大型模块使用动态导入:
async function loadFeature() {
const module = await import('./heavy-feature');
return module.default;
}遵循这些规范可以确保代码的一致性、可维护性和可读性。