TypeScript 最佳实践:编写更好的类型安全代码
TypeScript 已经成为现代前端开发的标准工具。在这篇文章中,我将分享一些实用的 TypeScript 最佳实践。
1. 使用严格模式
在 tsconfig.json 中启用严格模式:
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true
}
}
2. 优先使用接口而非类型别名
对于对象类型,推荐使用 interface:
// ✅ 推荐
interface User {
id: string;
name: string;
email: string;
}
// ❌ 不推荐(除非需要联合类型等高级特性)
type User = {
id: string;
name: string;
email: string;
};
3. 善用泛型
泛型让代码更加灵活和可复用:
// 通用的 API 响应类型
interface ApiResponse<T> {
data: T;
status: number;
message: string;
}
// 使用
const userResponse: ApiResponse<User> = {
data: { id: '1', name: 'John', email: 'john@example.com' },
status: 200,
message: 'Success',
};
4. 使用枚举管理常量
enum UserRole {
Admin = 'ADMIN',
User = 'USER',
Guest = 'GUEST',
}
function checkPermission(role: UserRole) {
if (role === UserRole.Admin) {
// 管理员权限
}
}
5. 类型守卫
使用类型守卫进行运行时类型检查:
interface Dog {
bark: () => void;
}
interface Cat {
meow: () => void;
}
function isDog(animal: Dog | Cat): animal is Dog {
return (animal as Dog).bark !== undefined;
}
function handleAnimal(animal: Dog | Cat) {
if (isDog(animal)) {
animal.bark(); // TypeScript 知道这里是 Dog
} else {
animal.meow(); // TypeScript 知道这里是 Cat
}
}
6. 使用 Utility Types
TypeScript 提供了许多实用的工具类型:
interface User {
id: string;
name: string;
email: string;
password: string;
}
// Partial - 所有属性变为可选
type PartialUser = Partial<User>;
// Pick - 选择特定属性
type UserPublicInfo = Pick<User, 'id' | 'name' | 'email'>;
// Omit - 排除特定属性
type UserWithoutPassword = Omit<User, 'password'>;
// Readonly - 所有属性变为只读
type ReadonlyUser = Readonly<User>;
7. 避免使用 any
尽量避免使用 any,如果不确定类型,使用 unknown:
// ❌ 不推荐
function processData(data: any) {
return data.value;
}
// ✅ 推荐
function processData(data: unknown) {
if (typeof data === 'object' && data !== null && 'value' in data) {
return (data as { value: string }).value;
}
throw new Error('Invalid data');
}
8. 使用 const assertions
// 普通对象
const config = {
endpoint: '/api',
timeout: 3000,
}; // 类型: { endpoint: string; timeout: number; }
// 使用 const assertion
const config = {
endpoint: '/api',
timeout: 3000,
} as const; // 类型: { readonly endpoint: '/api'; readonly timeout: 3000; }
9. 函数重载
为函数提供多个类型定义:
function formatDate(date: Date): string;
function formatDate(timestamp: number): string;
function formatDate(dateString: string): string;
function formatDate(input: Date | number | string): string {
const date = input instanceof Date ? input : new Date(input);
return date.toISOString();
}
10. 索引签名
当对象有动态键时:
interface Dictionary<T> {
[key: string]: T;
}
const scores: Dictionary<number> = {
math: 95,
english: 88,
science: 92,
};
总结
掌握这些 TypeScript 最佳实践,可以帮助你:
- 📝 编写更安全的代码
- 🐛 减少运行时错误
- 🔧 提高代码可维护性
- 💡 获得更好的 IDE 支持
记住:TypeScript 的目标不是增加复杂性,而是通过类型系统帮助我们写出更好的代码。
你有什么 TypeScript 的使用技巧想分享吗?欢迎在评论区交流!