一、由函数类比泛型
// 函数
const f = (a, b) => a + b
const result = f(1, 2)
// 泛型
// Union等价于函数名,<A, B>等价于参数,A|B等价于函数的返回值
type Union<A, B> = A | B
type union = Union<string, number> // type union = string | number
注: 函数的本质是推后执行的、部分待定的代码;泛型的本质是推后执行的、部分待定的类型。
二、泛型练习
- 简单泛型
type Union<A, B> = A | B
type union = Union<string, number> // string | number
type Union3<A, B, C> = A & B & C
type union3 = Union3<string, number, boolean> // string&number&boolean
interface List<A> {
[i: number]: A
}
type list = List<number>
interface Hash<A> {
[key: string]: A
}
type hash1 = Hash<string>
type hash2 = Hash<hash1>
- 使用关键字 extends(包含于即小于等于) 的泛型
// T 包含于 string 类型 ? true : false
type LikeString<T> = T extends string ? true : false
type S1 = LikeString<'hi'> // true
type S2 = LikeString<1> // false
type S3 = LikeString<never> // never
type LikeNumber<T> = T extends number ? 1 : 2
type N1 = LikeNumber<100> // 1
type N2 = LikeNumber<'100'> // 2
type Person = { name: string }
type LikePerson<T> = T extends Person ? 'yes' : 'no'
type isP1 = LikePerson<{ name: 'rourou1' }> // yes
type isP2 = LikePerson<{ name: 'rourou2', age: 18 }> // yes
type isP3 = LikePerson<{ age: 19 }> // no
type LikeArray<T> = T extends unknown ? T[] : never
type A1 = LikeArray<string> // string[]
type A2 = LikeArray<number> // number[]
// string extends unknown ? string[] : never
// | number extends unknow ? number[] : number
type A3 = LikeArray<string|number> // string[] | number[](泛型中:可以记做分配率)
type A4 = LikeArray<never> // never
注:在泛型中
- 当 T 是联合类型,则分开计算(分配率)(见 A3)
- 当 T 为 never,则表达式的值为 never;比如 type X = never extends unknown ? 1 : 2 这里 X 值为 never
- 使用关键字 keyof 的泛型
// 例一
type Person = {
name: string,
age: number
}
type GetKeys<T> = keyof T
type keys = GetKeys<Person> // name | age
const k1: keys = 'name'
const k2: keys = '1' // 报错
// 例二
type A = {
[k: string]: number
}
type B = {
[k in string]: number
}
type C = keyof A // string | number (可以联想,平时开发时对象的key有可能直接用数字表示)
type D = keyof B // string
- extends 和 keyof 一起用(T[K] 含义为获取 T 类型中 K 的类型)
type Person = {
name: string,
age: number
}
// K 包含于 keyof T 中,keyof T 值为 'name' | 'age'
// T[K] 含义为获取 T 类型中 K 的类型
type GetKeyType<T, K extends keyof T> = T[K]
type t1 = GetKeyType<Person, 'name'> // string
// 报错 类型 x 不满足约束 keyof Person
type t2 = GetKeyType<Person, 'x'>
- Readonly---作用:将类型的每个属性都加上 readonly
// in 代表映射,一一对应就是映射即一个属性对应一个属性
type Readonly<T> = {
readonly [K in keyof T]: T[K]
}
type Person = {
name: string,
age: number
}
type P = Readonly<Person> // { readonly name: string, readonly age: string }
- Partial---作用:将每个属性都加上可选标识
type Partial<T> = {
[K in keyof T]?: T[K]
}
type Person = {
name: string,
age: number
}
type p = Partial<Person> // { name?: string, age?: number }
- Required---作用:将每个属性都变为必选
type Required<T> = {
[K in keyof T]-?: T[K]
}
type Person = {
name?: string,
age?: number
}
type p = Required<Person> // { name: string, age: number }
- Record--作用:构造一个对象类型
type Record<Key extends string | number | symbol, Value> = {
[k in Key]: Value
}
type R = Record<string, number> // 等价于 type R = { [k: string]: number }
- Exclude--作用:求差集
type Exclude<T, P> = T extends P ? never : T
// 1 extends 1 | 2 ? never : 1
// | 2 extends 1 | 2 ? never : 2
// | 3 extends 1 | 2 ? never : 3
// never | never | 3 = 3
type E = Exclude<1 | 2 | 3, 1 | 2> // 3
- extract--作用:求交集
type Extract<T, P> = T extends P ? T : never
// 1 extends 2 | 3 | 5 ? 1 : never
// | 2 extends 2 | 3 | 5 ? 2 : never
// | 3 extends 2 | 3 | 5 ? 3 : never
// never | 2 | 3 = 2 | 3
type E = Extract<1 | 2 | 3, 2 | 3 | 5> // 2 | 3
- Omit--作用:筛选不包含 Keys 的类型
type Person = {
name: 'string',
age: number,
id: number
}
type Omit<T, Keys> = {
[K in keyof T as (K extends Keys ? never : K)]: T[K]
}
// [k in keyof Person] k 为 'name' | 'age' | 'id'
// K extends Keys ===> 'name' | 'age' | 'id' extends 'name' | 'age' ? never : ...
// K 最后就剩下 id, T[K] ===> Person[id]===> 'id': number
type O = Omit<Person, 'name' | 'age'> // { id: number }
- Pick--作用:筛选包含 Keys 的类型
type Person = {
name: 'string',
age: number,
id: number
}
// 这里不写 Keys extends keyof T 会报错
// 因为 Keys 映射成 K 后,如果 K 不在 keyof T 中第二行的 T[K]就找不到了
type Pick1<T, Keys extends keyof T> = {
[K in Keys]: T[K]
}
type P = Pick1<Person, 'name' | 'age'>
// 利用 Pick 和 Exclude 重写 Omit
type Omit<T, Keys> = Pick<T, Exclude<keyof T, Keys>>
- Mutable--作用:将
type Mutable<T> = {
-readonly [K in keyof T]: T[K]
};