typescript-best-practices
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTypeScript Best Practices
TypeScript 最佳实践
Quick Start
快速入门
Always enable strict mode and use explicit types for public APIs. Prefer type-only imports () and named exports over default exports. Use discriminated unions for state management and type guards for runtime validation.
import type始终启用严格模式,并为公共API使用显式类型。优先使用仅类型导入()和命名导出而非默认导出。使用判别式联合进行状态管理,使用类型守卫进行运行时验证。
import typeType Safety Fundamentals
类型安全基础
Strict Mode Configuration
严格模式配置
Enable all strict flags in :
tsconfig.jsonjson
{
"strict": true,
"noImplicitAny": true,
"noImplicitReturns": true,
"strictNullChecks": true,
"strictFunctionTypes": true
}在中启用所有严格标志:
tsconfig.jsonjson
{
"strict": true,
"noImplicitAny": true,
"noImplicitReturns": true,
"strictNullChecks": true,
"strictFunctionTypes": true
}Null Safety
空值安全
typescript
// Explicit null handling
export function findById<T>(items: Map<string, T>, id: string): T | null {
return items.get(id) ?? null;
}
// Optional chaining and nullish coalescing
export function getName(item?: Item): string {
return item?.name ?? 'Unknown';
}typescript
// 显式空值处理
export function findById<T>(items: Map<string, T>, id: string): T | null {
return items.get(id) ?? null;
}
// 可选链和空值合并
export function getName(item?: Item): string {
return item?.name ?? 'Unknown';
}Explicit Return Types
显式返回类型
Use explicit return types for public APIs:
typescript
// Good
export function validateConfig(data: unknown): ValidatedConfig | null {
const result = ConfigSchema.safeParse(data);
return result.success ? result.data : null;
}
// Bad - implicit return type
export function validateConfig(data) {
return data;
}为公共API使用显式返回类型:
typescript
// 推荐写法
export function validateConfig(data: unknown): ValidatedConfig | null {
const result = ConfigSchema.safeParse(data);
return result.success ? result.data : null;
}
// 不推荐写法 - 隐式返回类型
export function validateConfig(data) {
return data;
}Core Patterns
核心模式
Discriminated Unions for State
用于状态管理的判别式联合
typescript
export type ConnectionState =
| { status: 'disconnected' }
| { status: 'connecting'; progress: number }
| { status: 'connected'; connectionId: string }
| { status: 'error'; message: string };
// TypeScript knows which properties are available in each branchtypescript
export type ConnectionState =
| { status: 'disconnected' }
| { status: 'connecting'; progress: number }
| { status: 'connected'; connectionId: string }
| { status: 'error'; message: string };
// TypeScript 会知晓每个分支中可用的属性Result Type for Error Handling
用于错误处理的结果类型
typescript
export type Result<T, E = Error> =
| { success: true; data: T }
| { success: false; error: E };
const result = await connectToService(options);
if (result.success) {
console.log('Connected:', result.data.id);
} else {
console.error('Failed:', result.error.message);
}typescript
export type Result<T, E = Error> =
| { success: true; data: T }
| { success: false; error: E };
const result = await connectToService(options);
if (result.success) {
console.log('已连接:', result.data.id);
} else {
console.error('连接失败:', result.error.message);
}Readonly Properties
只读属性
Use for immutable data:
readonlytypescript
export interface Config {
readonly enableFeature: boolean;
readonly port: number;
}为不可变数据使用:
readonlytypescript
export interface Config {
readonly enableFeature: boolean;
readonly port: number;
}Type Guards and Assertions
类型守卫与断言
typescript
// Type guard
export function isUserData(data: unknown): data is UserData {
return typeof data === 'object' && data !== null && 'name' in data;
}
// Assertion function
export function assertIsDefined<T>(value: T): asserts value is NonNullable<T> {
if (value === undefined || value === null) throw new Error('Value is undefined or null');
}typescript
// 类型守卫
export function isUserData(data: unknown): data is UserData {
return typeof data === 'object' && data !== null && 'name' in data;
}
// 断言函数
export function assertIsDefined<T>(value: T): asserts value is NonNullable<T> {
if (value === undefined || value === null) throw new Error('值为undefined或null');
}Import/Export Conventions
导入/导出约定
typescript
// Type-only imports (preferred)
import type { Config } from '../types/config';
// Named exports (avoid default exports)
export class DataService {}
export const getService = () => DataService.getInstance();
// Grouped imports
import { External } from 'external'; // External deps
import { internalUtil } from './utils'; // Internal utils
import type { MyType } from './types'; // Typestypescript
// 仅类型导入(推荐)
import type { Config } from '../types/config';
// 命名导出(避免默认导出)
export class DataService {}
export const getService = () => DataService.getInstance();
// 分组导入
import { External } from 'external'; // 外部依赖
import { internalUtil } from './utils'; // 内部工具
import type { MyType } from './types'; // 类型When to Use References
何时使用参考文档
| Reference File | When to Load |
|---|---|
| Setting up TypeScript configuration |
| Defining interfaces, generic types, extending external types |
| Working with discriminated unions, result types, exhaustive checks |
| Runtime validation, branded types, assertion functions |
| Using built-in utilities, const assertions, template literal types |
| Implementing structured errors, error factories, retry logic |
| Building generic services, repositories, factories, event emitters |
| Organizing imports/exports, avoiding circular dependencies |
| 参考文件 | 适用场景 |
|---|---|
| 设置TypeScript配置时 |
| 定义接口、泛型类型、扩展外部类型时 |
| 处理判别式联合、结果类型、穷尽性检查时 |
| 运行时验证、品牌类型、断言函数时 |
| 使用内置工具、const断言、模板字面量类型时 |
| 实现结构化错误、错误工厂、重试逻辑时 |
| 构建泛型服务、仓库、工厂、事件发射器时 |
| 组织导入/导出、避免循环依赖时 |
Common Anti-Patterns to Avoid
需避免的常见反模式
- Using - Use
anywith type guards insteadunknown - Default exports - Harder to refactor and tree-shake
- Implicit return types on public APIs
- Non-readonly interfaces for immutable data
- Nested optionals () - use discriminated unions instead
{ a?: { b?: string } }
- 使用- 改用
any搭配类型守卫unknown - 默认导出 - 更难重构和摇树优化
- 公共API使用隐式返回类型
- 不可变数据使用非只读接口
- 嵌套可选类型()- 改用判别式联合
{ a?: { b?: string } }