2025-01-20 · 4 min read
TypeScript 实用技巧和最佳实践
#typescript#programming#best-practices
前言
TypeScript 已经成为现代 JavaScript 开发的标准选择。它不仅提供了类型安全,还带来了更好的开发体验和代码可维护性。本文将分享一些实用的 TypeScript 技巧和最佳实践。
类型推断和类型注解
让 TypeScript 推断类型
typescript
// ✅ 好的做法:让 TypeScript 推断类型
const users = ['Alice', 'Bob', 'Charlie']
// ❌ 不必要的类型注解
const users: string[] = ['Alice', 'Bob', 'Charlie']使用 const 断言
typescript
// 普通数组
const colors = ['red', 'green', 'blue'] // string[]
// 使用 as const
const colors = ['red', 'green', 'blue'] as const // readonly ["red", "green", "blue"]
// 对象字面量
const config = {
apiUrl: 'https://api.example.com',
timeout: 5000,
} as const实用工具类型
Partial 和 Required
typescript
interface User {
name: string
email: string
age: number
}
// 所有属性变为可选
type PartialUser = Partial<User>
// { name?: string; email?: string; age?: number }
// 所有属性变为必需
type RequiredUser = Required<PartialUser>Pick 和 Omit
typescript
interface User {
id: number
name: string
email: string
password: string
}
// 选择特定属性
type PublicUser = Pick<User, 'id' | 'name' | 'email'>
// 排除特定属性
type UserWithoutPassword = Omit<User, 'password'>Record 类型
typescript
// 创建键值对类型
type Status = 'pending' | 'approved' | 'rejected'
type StatusConfig = Record<Status, { color: string; message: string }>
const config: StatusConfig = {
pending: { color: 'yellow', message: '等待审核' },
approved: { color: 'green', message: '已通过' },
rejected: { color: 'red', message: '已拒绝' },
}函数类型
函数重载
typescript
function format(value: string): string
function format(value: number): string
function format(value: boolean): string
function format(value: string | number | boolean): string {
return String(value)
}泛型函数
typescript
// 简单的泛型函数
function identity<T>(arg: T): T {
return arg
}
// 带约束的泛型
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key]
}
const user = { name: 'Alice', age: 30 }
const name = getProperty(user, 'name') // string
const age = getProperty(user, 'age') // number类型守卫
typescript
// 类型守卫函数
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())
}
}
// 自定义类型守卫
interface Cat {
type: 'cat'
meow: () => void
}
interface Dog {
type: 'dog'
bark: () => void
}
function isCat(animal: Cat | Dog): animal is Cat {
return animal.type === 'cat'
}条件类型
typescript
// 基础条件类型
type NonNullable<T> = T extends null | undefined ? never : T
// 分布式条件类型
type ToArray<T> = T extends any ? T[] : never
type StrArrOrNumArr = ToArray<string | number> // string[] | number[]
// 实用示例:提取 Promise 类型
type Awaited<T> = T extends Promise<infer U> ? U : T模板字面量类型
typescript
type EventName<T extends string> = `on${Capitalize<T>}`
type ClickEvent = EventName<'click'> // 'onClick'
type ChangeEvent = EventName<'change'> // 'onChange'
// 结合联合类型
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE'
type ApiEndpoint = `/api/${string}`
type ApiRoute = `${HttpMethod} ${ApiEndpoint}`错误处理
typescript
// Result 类型模式
type Result<T, E = Error> = { success: true; data: 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, data: a / b }
}
// 使用
const result = divide(10, 2)
if (result.success) {
console.log(result.data) // TypeScript 知道 data 存在
} else {
console.error(result.error) // TypeScript 知道 error 存在
}最佳实践
- 避免使用
any:使用unknown代替 - 启用严格模式:
strict: true在 tsconfig.json - 使用类型而不是接口:对于联合类型和交叉类型
- 利用类型推断:不要过度注解类型
- 使用 const 断言:获得更精确的类型
总结
TypeScript 提供了强大的类型系统,合理使用这些技巧可以显著提升代码质量和开发效率。记住,类型系统是你的朋友,让它帮助你写出更好的代码!