TypeScript最佳实践 #

一、类型设计 #

1.1 优先使用interface #

typescript
interface User {
    name: string;
    age: number;
}

type ID = string | number;
type Status = 'pending' | 'approved';

1.2 避免使用any #

typescript
function process(value: unknown): void {
    if (typeof value === 'string') {
        console.log(value.toUpperCase());
    }
}

1.3 使用字面量类型 #

typescript
type Direction = 'up' | 'down' | 'left' | 'right';

function move(direction: Direction): void {
    console.log(direction);
}

1.4 使用可辨识联合 #

typescript
interface Circle {
    kind: 'circle';
    radius: number;
}

interface Square {
    kind: 'square';
    sideLength: number;
}

type Shape = Circle | Square;

function getArea(shape: Shape): number {
    switch (shape.kind) {
        case 'circle':
            return Math.PI * shape.radius ** 2;
        case 'square':
            return shape.sideLength ** 2;
    }
}

二、函数设计 #

2.1 显式返回类型 #

typescript
function add(a: number, b: number): number {
    return a + b;
}

async function fetchUser(id: number): Promise<User> {
    const response = await fetch(`/api/users/${id}`);
    return response.json();
}

2.2 使用函数重载 #

typescript
function createElement(tag: 'a'): HTMLAnchorElement;
function createElement(tag: 'canvas'): HTMLCanvasElement;
function createElement(tag: string): HTMLElement {
    return document.createElement(tag);
}

2.3 使用泛型 #

typescript
function identity<T>(arg: T): T {
    return arg;
}

async function fetchJson<T>(url: string): Promise<T> {
    const response = await fetch(url);
    return response.json();
}

三、类设计 #

3.1 使用访问修饰符 #

typescript
class User {
    private password: string;
    protected createdAt: Date;
    public name: string;
    
    constructor(name: string, password: string) {
        this.name = name;
        this.password = password;
        this.createdAt = new Date();
    }
}

3.2 使用readonly #

typescript
class Config {
    readonly apiUrl: string;
    
    constructor() {
        this.apiUrl = process.env.API_URL!;
    }
}

3.3 优先组合而非继承 #

typescript
interface Logger {
    log(message: string): void;
}

interface Database {
    save(data: any): void;
}

class UserService {
    constructor(
        private logger: Logger,
        private database: Database
    ) {}
    
    save(user: User): void {
        this.logger.log('Saving user');
        this.database.save(user);
    }
}

四、模块设计 #

4.1 使用ES模块 #

typescript
export interface User {
    name: string;
}

export function greet(user: User): string {
    return `Hello, ${user.name}!`;
}

4.2 使用类型导入 #

typescript
import type { User } from './types';
import { greet } from './utils';

4.3 使用路径别名 #

typescript
import { Button } from '@components/Button';
import { formatDate } from '@utils/date';

五、错误处理 #

5.1 使用Result模式 #

typescript
type Result<T, E = Error> = {
    success: true;
    value: T;
} | {
    success: false;
    error: E;
};

function divide(a: number, b: number): Result<number> {
    if (b === 0) {
        return { success: false, error: new Error('Division by zero') };
    }
    return { success: true, value: a / b };
}

5.2 自定义错误类型 #

typescript
class ValidationError extends Error {
    constructor(public field: string, message: string) {
        super(message);
        this.name = 'ValidationError';
    }
}

function validate(user: User): void {
    if (!user.name) {
        throw new ValidationError('name', 'Name is required');
    }
}

六、性能优化 #

6.1 使用const枚举 #

typescript
const enum Direction {
    Up,
    Down,
    Left,
    Right
}

function move(direction: Direction): void {
    console.log(direction);
}

6.2 避免过度类型检查 #

typescript
type DeepPartial<T> = {
    [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};

6.3 使用类型导入 #

typescript
import type { User } from './types';

七、代码组织 #

7.1 项目结构 #

text
src/
├── components/
│   ├── Button/
│   │   ├── index.ts
│   │   └── Button.tsx
│   └── index.ts
├── hooks/
│   └── useUser.ts
├── services/
│   └── UserService.ts
├── types/
│   └── index.ts
├── utils/
│   └── date.ts
└── index.ts

7.2 类型文件组织 #

typescript
export interface User {
    id: number;
    name: string;
}

export type Status = 'pending' | 'approved';

export interface ApiResponse<T> {
    code: number;
    data: T;
}

八、总结 #

本章介绍了TypeScript最佳实践:

类型设计 #

  1. 优先使用interface
  2. 避免使用any
  3. 使用字面量类型
  4. 使用可辨识联合

代码组织 #

  1. 使用ES模块
  2. 使用类型导入
  3. 合理组织项目结构

性能优化 #

  1. 使用const枚举
  2. 避免过度类型检查
  3. 使用类型导入
最后更新:2026-03-26