TS-8 泛型
2023-03-14 本文已影响0人
RickyWu585
- 函数的本质是
推后执行的,部分待定的
一段代码 - 泛型的本质是
推后执行的,部分待定的
类型 -
T extends string
的意思是T是string的子集或者T和string正好重合,也就是包含于
type Person = {
name: string
}
// 这里extends可以用类型兼容来理解
type LikePerson<T> = T extends Person ? 'yes' : 'no'
type A = LikePerson<{name: string,age: number}> // yes
type B = LikePerson<string> // no
- 如果泛型是
联合类型
且用到了extends
,就会分别计算
,类似于先进行类型收窄
,也类似于乘法分配律
-
extends
与never
,如果泛型
传一个never
,那么这个类型直接返回never
,类似于乘法中的0 * n = 0
- 上述两个规则
只对泛型有效
type ToArray<T> = T extends unknown ? T[] : 'xxx'
type A = ToArray<string | number> // string[] | number[]
type B = ToArray<never> //never
keyof
type Person = {
name: string
age: number
}
type GetKeys<T> = keyof T
type PersonKeys = GetKeys<Person> // 'name' | 'string'
T[K]
type Person = {
name: string
age: number
}
// 泛型约束
type GetKeyType<T,K extends keyof T> = T[K]
type Result = GetKeyType<Person,'age'> // number
- 给泛型加
extends ...
就属于泛型约束
type GetKeyType<T,K extends keyof T> = T[K]
- 映射类型
in
,多用于泛型,一般是对keyof返回的string联合类型
做一个遍历map
,能保证与之前的类型一一对应
type Person = {
name: string
age: number
}
type ReadOnlyType<T> = {
readonly [K in keyof T]: T[K]
}
type A = ReadOnlyType<Person> // {readonly name: string; readonly age:number}
- 泛型实践:
type Person = {
name: string
age: number
}
// 所有属性必填
type Required<T> = {
[K in keyof T] -? : T[K]
}
// K 是泛型,不能用 [k : K],只能用 in
type Record<K extends string | number | symbol,T> = {
[k in K] : T
}
// 对 T 做分配律,分配律只对前面的有效
type Exclude<T,K > = T extends K ? never : T
type X = Exclude<1 | 2 | 3,1 | 2> // 3
// ---相反---
type Extract<T,K> = K extends T ? K : never
type Y = Extract<1 | 2 | 3,2 | 4> // 2
type Pick<T,K extends keyof T> = {
[k in K]: T[k]
}
type Omit<T,Key extends keyof T> = Pick<T,Exclude<keyof T,Key>>
// ---or---
type Omit<T,Key extends keyof T> = {
[k in keyof T as (k extends Key ? never : k)] : T[k]
}
type Z = Omit<Person,'age'> // {name: string}
// -readonly
type Mutable<T> = {
-readonly [k in keyof T]: T[k]
}
-
Awaited
:获取promise data的类型