TypeScript类型体操进阶:掌握高级类型系统

TypeScript类型系统进阶 TypeScript的类型系统非常强大,掌握高级类型特性可以帮助我们写出更安全、更优雅的代码。 条件类型 基础条件类型 1 2 3 4 5 6 7 8 9 10 // 类似三元表达式 type IsString<T> = T extends string ? true : false type Test1 = IsString<string> // true type Test2 = IsString<number> // false // 嵌套条件类型 type NonNullable<T> = T extends null | undefined ? never : T type Test3 = NonNullable<string | null> // string 分布式条件类型 1 2 3 4 5 6 7 8 9 // 联合类型会分布式应用条件类型 type ToArray<T> = T extends any ? T[] : never type Test4 = ToArray<string | number> // string[] | number[] // 阻止分布 type ToArrayNonDistributive<T> = [T] extends [any] ? T[] : never type Test5 = ToArrayNonDistributive<string | number> // (string | number)[] 类型推断 1 2 3 4 5 6 7 8 9 10 // Infer关键字 type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never type Fn = (x: number) => string type Test6 = ReturnType<Fn> // string // 解包Promise type UnwrapPromise<T> = T extends Promise<infer U> ? U : T type Test7 = UnwrapPromise<Promise<string>> // string 映射类型 基础映射类型 1 2 3 4 5 6 7 8 9 10 11 12 13 14 // 将所有属性变为可选 type Partial<T> = { [P in keyof T]?: T[P] } // 将所有属性变为必需 type Required<T> = { [P in keyof T]-?: T[P] } // 只读 type Readonly<T> = { readonly [P in keyof T]: T[P] } 高级映射类型 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 // 只保留特定类型 type OnlyStrings<T> = { [P in keyof T as T[P] extends string ? P : never]: T[P] } interface User { name: string age: number email: string } type Test8 = OnlyStrings<User> // { name: string; email: string } // 条件映射 type Getters<T> = { [P in keyof T as `get${Capitalize<string & P>}`]: () => T[P] } type Test9 = Getters<{ name: string; age: number }> // { getName: () => string; getAge: () => number } 模板字面量类型 基础用法 1 2 3 4 type Greeting = `hello ${string}` const test: Greeting = 'hello world' // ✓ const test2: Greeting = 'hi world' // ✗ 高级应用 1 2 3 4 5 6 7 8 9 10 // 事件名称类型 type EventName<T extends string> = `on${Capitalize<T>}` type Test10 = EventName<'click'> // 'onClick' // 路径类型 type Path<T extends string> = `/${T}` | `${Path<T>}/${T}` // 组合类型 type CssValue<T extends number> = `${T}px` | `${T}%` | `${t}em` 递归类型 深度只读 1 2 3 4 5 6 7 8 9 10 11 12 13 type DeepReadonly<T> = { readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P] } interface Config { database: { host: string port: number } } type Test11 = DeepReadonly<Config> // 所有嵌套属性都变为只读 深度必需 1 2 3 type DeepRequired<T> = { [P in keyof T]-?: T[P] extends object ? DeepRequired<T[P]> : T[P] } 品牌类型 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // 创建唯一类型 type Brand<T, B> = T & { __brand: B } type USD = Brand<number, 'USD'> type EUR = Brand<number, 'EUR'> const usd: USD = 100 as USD const eur: EUR = 100 as EUR // 不能直接赋值 // eur = usd // ✗ 类型错误 function addUSD(a: USD, b: USD): USD { return (a + b) as USD } 函数类型高级应用 函数重载 1 2 3 4 5 6 7 8 function process(input: string): string function process(input: number): number function process(input: string | number): string | number { return input } const result1 = process('hello') // string const result2 = process(123) // number 参数类型推断 1 2 3 4 5 6 7 8 9 10 // 元组转函数参数 type TupleToFn<T extends any[]> = T extends [...infer Args, infer R] ? (...args: Args) => R : never type Test12 = TupleToFn<[string, number, boolean]> // 反向推断 type FnToTuple<T extends (...args: any[]) => any> = T extends (...args: infer A) => any ? A : never 类型守卫 typeof守卫 1 2 3 4 5 6 7 8 9 10 function isString(value: unknown): value is string { return typeof value === 'string' } function process(value: unknown) { if (isString(value)) { // 这里value的类型是string console.log(value.toUpperCase()) } } in守卫 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 interface Cat { meow(): void } interface Dog { bark(): void } function makeSound(animal: Cat | Dog) { if ('meow' in animal) { animal.meow() } else { animal.bark() } } instanceof守卫 1 2 3 4 5 6 7 8 9 10 11 12 13 class Error1 extends Error { code = 'ERROR_1' } class Error2 extends Error { code = 'ERROR_2' } function handleError(error: Error) { if (error instanceof Error1) { console.log(error.code) } } 高级工具类型 OmitByType 1 2 3 4 5 6 7 8 9 10 11 12 type OmitByType<T, U> = { [P in keyof T as T[P] extends U ? never : P]: T[P] } interface Test { name: string age: number active: boolean } type Test13 = OmitByType<Test, boolean> // { name: string; age: number } DeepPick 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 type DeepPick<T, K extends string> = K extends `${infer Key}.${infer Rest}` ? Key extends keyof T ? { [P in Key]: DeepPick<T[P], Rest> } : never : K extends keyof T ? { [P in K]: T[K] } : never interface User { profile: { name: string email: string } settings: { theme: string } } type Test14 = DeepPick<User, 'profile.name'> // { profile: { name: string } } 实战案例 表单类型定义 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 type FieldProps<T> = { value: T onChange: (value: T) => void error?: string } type FormFields<T> = { [K in keyof T]: FieldProps<T[K]> } interface LoginData { email: string password: string remember: boolean } type LoginForm = FormFields<LoginData> API响应类型 1 2 3 4 5 6 type ApiResponse<T, E = Error> = | { success: true; data: T } | { success: false; error: E } type UserResponse = ApiResponse<User> type ErrorResponse = ApiResponse<never, NetworkError> 最佳实践 优先使用类型推导 - 让TypeScript自动推导类型 避免使用any - 使用unknown代替 合理使用泛型 - 提高代码复用性 类型守卫 - 缩小类型范围 品牌类型 - 创建语义化类型 总结 TypeScript类型系统非常强大,掌握高级类型特性可以帮助我们构建更安全的代码。 ...