🎯 TypeScript 核心优势#
TypeScript 作为 JavaScript 的超集,通过静态类型检查帮助我们在开发阶段发现潜在问题,提升代码质量和开发体验。
✨ 主要特性#
- 静态类型检查: 编译时发现类型错误
- 智能提示: IDE 提供准确的代码补全
- 重构安全: 类型安全的重构操作
- 文档化: 类型即文档,提高代码可读性
🏗️ 类型定义最佳实践#
1. 接口 vs 类型别名#
// 推荐:使用接口定义对象结构
interface User {
id: number;
name: string;
email: string;
isActive?: boolean; // 可选属性
}
// 推荐:使用类型别名定义联合类型或复杂类型
type Status = 'pending' | 'approved' | 'rejected';
type UserWithRole = User & { role: 'admin' | 'user' };
2. 泛型的使用#
// 通用函数
function identity<T>(arg: T): T {
return arg;
}
// 泛型接口
interface ApiResponse<T> {
data: T;
status: number;
message: string;
}
// 泛型约束
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
🔒 类型安全技巧#
1. 严格模式配置#
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true
}
}
2. 类型守卫#
// 类型谓词
function isString(value: unknown): value is string {
return typeof value === 'string';
}
// 使用类型守卫
function processValue(value: unknown) {
if (isString(value)) {
// TypeScript 知道 value 是 string 类型
console.log(value.toUpperCase());
}
}
🎨 代码组织#
1. 模块化设计#
// user.types.ts
export interface User {
id: number;
name: string;
}
// user.service.ts
import { User } from './user.types';
export class UserService {
async getUser(id: number): Promise<User> {
// 实现逻辑
}
}
2. 命名空间 vs 模块#
// 推荐:使用模块
// math.ts
export function add(a: number, b: number): number {
return a + b;
}
// 避免:命名空间
namespace Math {
export function add(a: number, b: number): number {
return a + b;
}
}
🚀 性能优化#
1. 类型推断#
// 让 TypeScript 自动推断类型
const numbers = [1, 2, 3, 4, 5]; // 类型: number[]
const user = { name: 'John', age: 30 }; // 类型: { name: string; age: number }
// 避免过度类型注解
// 不推荐
const name: string = 'John';
// 推荐
const name = 'John';
2. 条件类型#
type NonNullable<T> = T extends null | undefined ? never : T;
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;
🔧 实用工具类型#
1. 内置工具类型#
// 部分属性可选
type PartialUser = Partial<User>;
// 所有属性只读
type ReadonlyUser = Readonly<User>;
// 选择特定属性
type UserName = Pick<User, 'name' | 'email'>;
// 排除特定属性
type UserWithoutId = Omit<User, 'id'>;
2. 自定义工具类型#
// 深度部分可选
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};
// 递归只读
type DeepReadonly<T> = {
readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
};
📝 错误处理#
1. Result 类型模式#
type Result<T, E = Error> =
| { success: true; data: T }
| { success: false; error: E };
async function fetchUser(id: number): Promise<Result<User>> {
try {
const user = await api.getUser(id);
return { success: true, data: user };
} catch (error) {
return { success: false, error: error as Error };
}
}
2. 异常类型#
class ValidationError extends Error {
constructor(
message: string,
public field: string,
public value: unknown
) {
super(message);
this.name = 'ValidationError';
}
}
🧪 测试策略#
1. 类型测试#
// 确保类型正确
type Assert<T extends true> = T;
type IsString<T> = T extends string ? true : false;
// 类型测试
type Test1 = Assert<IsString<'hello'>>; // true
type Test2 = Assert<IsString<123>>; // 编译错误
2. 测试工具#
// 使用 tsd 进行类型测试
import { expectType } from 'tsd';
expectType<string>('hello');
expectType<number>(123);
💡 最佳实践总结#
- 启用严格模式: 充分利用 TypeScript 的类型检查
- 优先使用接口: 定义对象结构时使用接口
- 合理使用泛型: 提高代码复用性和类型安全性
- 避免 any 类型: 尽可能使用具体类型
- 利用类型推断: 让 TypeScript 自动推断类型
- 使用工具类型: 减少重复的类型定义
- 模块化设计: 使用 ES6 模块而不是命名空间
📚 学习资源#
掌握这些最佳实践,让你的 TypeScript 代码更加健壮和易维护!