TypeScript - -类型实战
下面介绍的几个常见实战操作,数量不多,但是提供了一些思路, 学习理解这些思路,和js 实现的区别。为自己写代码的时候打下小小的基础
1. 实现返回 promise 返回值类型的类
type UnwrapPromise<T> = T extends Promise<infer U> ? U: Error
type A = UnwrapPromise<Promise<string>>
2. 实现includes
type T1 = includes<[1,2,3,4], 5> // false
type T2 = includes<['a',2,3,4], 'a'> // true
按照上面的举的列子, 就是要实现 includes 它接收两个参数, 第一个参数是个数组, 第二个参数时基础数据类型,如果第二个参数在一个数组中的元素类型中, 就返回 true 否则 返回 false
type includes<T extends readonly any[], P> = P extends T[number] ? true : false
应为第一个参数时数组, 所以 P extends T[number] 就是看下 P 是不是在第一个数组的元素类型中
3. 实现push
type A = push<[1,2,3], 4> // [1,2,3,4]
type B = push<[1], 2> // [1,2]
type C = push<[], string> [string]
就是传入两个参数,第一个参数时个数组类型, 第二个参数时任意的, 然后返回的类型就是将第二个参数 添加到数组中, 返回最新的类型
type Push<T extends any[], I> = T extends [...infer P] ? [...P,I] : [I]
4. 实现getValue
就是实现一个方法, 第一个参数为类, 第二个参数是类中的一个属性,返回该属性的值
interface Person {
name: string;
age: number;
}
const tom: Person = {
name: 'tom',
age: 34
}
function getValue () {
...
}
const name = getValue(tom, 'name') // string
const age = getValue(tom, 'age') // number
实现如下
function getValue<T, K extends keyof T>(data: T, key: K): T[K] {
return data[key]
}
5. 实现Repeat
实现一个Repeat 接收两个参数, 第一个参数是一个任意的类型, 第二个参数是个数字, 返回一个元组, 元组的长度就是数字, 每个值就是传入的第一个参数
tyoe A = Repeat(number, 3) // [number, number, number]
tyoe B = Repeat(string, 3) // [string, string, string]
tyoe C = Repeat(1, 2) // [1, 1]
tyoe D = Repeat(0, 0) // []
实现如下
type Reapet<T, C, R extends any[] = []> = R['length'] extends C ? R : Reapet<T,C [...R,T]>
上面的实现中思路类似与js 中的递归思路, Reapet 参数中创建一个默认的第三个数组参数 R , 接下来判断 R数组的length 是不是满足第二个参数, 如果满足就返回 R 不满足将 继续调用 Reapet ,这个时候的第三个参数就是将 R 和 T 放在一个数组中, 传递给Reapet.