挑战类型体操答案合集,一部分是自己做的,一部分是自己抄的
热身运动
1 | // 期望是一个 string 类型 👉 so eazy |
部分前置知识: keyof, typeof, extends 等,具体请移步到官方文档查阅详情
1 | // typeof Type Operator |
实现 Pick<T, Keys>
1 | interface Todo { |
Readonly<T>
1 | interface Todo { |
DeepReadonly<T>
🌟
1 | type DeepReadonly<T> = { |
ReadonlyAndPick<T, Keys>
🌟
1 | type ReadonlyAndPick<T, K extends keyof T> = {readonly [P in keyof T as P extends K ? P : never]: T[P]} & {[P in keyof T as P extends K ? never : P]:[P]} |
Omit<T, Keys>
1 | interface Todo { |
Exclude<T, U>
1 | // 从T中排除可分配给U的类型 |
ReturnType<T>
提取函数的返回类型
1 | type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any |
Parameters<T>
提取函数的参数类型
1 | type Parameters<T> = T extends (...args: infer P) => any ? P : T |
First<T>
of Array 实现一个泛型类型, 使得可以返回数组类型的第一项
1 | type arr1 = ['a', 'b', 'c'] |
Length<T>
of Tuple
1 | type tesla = ['tesla', 'model3', 'model X', 'model Y'] |
Last<T>
of Array 实现一个泛型类型, 使得可以返回数组类型的最后一项
1 | type arr1 = ['a', 'b', 'c'] |
Concat<T, P>
: 实现一个Array.concat 方法功能相同的类型
1 | type Concat<T, P> =T extends any[] ? P extends any[] ? [...T, ...P] : never : never; |
Push<T, P>
: Array.push 类型方法
1 | type Push<T extends any[], P extends any> = [...T, P] |
Unshift<T, P>
: Array.unshift 类型方法
1 | type Unshift<T extends any[], P extends any> = [P, ...T] |
Pop<T>
🌟
1 | type Pop<T> = T extends [...infer P, infer E] ? P : never; |
Shift<T>
🌟
1 | type Shift<T> = T extends [infer E, ...infer P] ? P : never; |
Promise.all
🌟🌟
1 | type inferTupleT<T extends any[]> = { |
If<truthy, T, F>
🌟🌟
If<true, T, F> => T, If<false, T, F> => F
这里还需要考虑
any
,never
,boolean
被视为union type
, 同时 never是union运算的幺元【可在 category-theory-for-programmers 这本书上找到相关解释】, 但是unknown
却没有
1 | type If<C, T, F> = C extends true ? T : C extends false ? F : never; |
插播:conditional type & distributive conditional types
distributive conditional types 的3个前提条件:1. T = naked type; 2. T = checked type; 3. T 实例化为 union type;
1 | // T: checkedType 被检查的类型 |
TupleToUnion<T>
元组转联合类型
1 | type TupleToUnion<T extends any[]> = T[number] |
TupleToObject<T>
元组转对象
1 | type tuple = ['tesla', 'model 3', 'model X', 'model Y'] |
IsNever<T>
🌟
conditional type 判断 IsNever 在某种情况下有问题:如果这么写
type IsNever<T> = T extends never ? true : false
, 当type A = IsNever<never>
时type A = never
而不是 true or false, 查阅怎么理解 conditional type 中的联合类型与 never
1 | // IsNever |
Flatten<T>
1 | type Flatten<T> = T extends Array<infer I> ? I : T; |
TroubleShooting
- naked type: The type parameter is present without being wrapped in another type, (ie, an array, or a tuple, or a function, or a promise or any other generic type)