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最佳实践:
类型设计 #
- 优先使用interface
- 避免使用any
- 使用字面量类型
- 使用可辨识联合
代码组织 #
- 使用ES模块
- 使用类型导入
- 合理组织项目结构
性能优化 #
- 使用const枚举
- 避免过度类型检查
- 使用类型导入
最后更新:2026-03-26