TS-泛型
·
nanpangyou
TypeScript 泛型
- 简单泛型
type Union<A, B> = A | B
type Intersect<A, B> = A & B
interface List<A> {
[key: number]: A
}
interface Hash<T> {
[key: string]: T
}
- 稍微复杂一点的泛型(extends)
type Person = { name: string }
// 补全问号处,使得下面的代码能够正常工作
type LikeString<T> = ???
type LikeNumber<T> = ???
type LikePerson<T> = ???
// 答案
type LikeString<T> = T extends string ? true : false // T 所代表的集合要么是 string,要么是 string 的子集
type LikeNumber<T> = T extends number ? 1 : 2 // T 所代表的集合要么是 number,要么是 number 的子集
type LikePerson<T> = T extends Person ? 'yes' : 'no' // T 所代表的集合要么是 Person,要么是 Person 的子集
type R1 = LikeString<'hi'> // true
type R2 = LikeString<true> // false
type R3 = LikeNumber<6666> // 1
type R4 = LikeNumber<false> // 2
type R5 = LikePerson<{ name: 'frank', xxx: 1 }> // yes
type R6 = LikePerson<{ xxx: 1 }> // no
extends 有两点要注意
- 若 T 为 never,则表达式的值为 never
- 若 T 为联合类型,则分开计算
这两条规则只在泛型中有用,其他地方都不会有这种情况
type X1 = LikeString<never> // X1 的type为never
type ToArray<T> = T extends unknown ? T[] : never
type Result = ToArray<string | number> // Result 的type为 string[] | number[]
type Result2 = ToArray<never> // Result2 的type为 never
- 另一个稍微复杂一点的泛型(keyof)
type Person = { name: string, age: number }
type GetKeys<T> = ???
// 答案
type GetKeys<T> = keyof T
type Result = GetKeys<Person> // Result 的type为 'name' | 'age'
- 另一个稍微复杂一点的泛型(extends keyof) (泛型约束)
type Person = { name: string, age: number }
type GetKeyType = ???
// 答案
type GetKeyType<T, K extends keyof T> = T[K]
type Result = GetKeyType<Person, 'name'> // Result 的type为 string
type X = Person['name'] // X 的type为 string
- 复杂一点的泛型(TS自带的泛型)
type Person = { name: string, age: number }
type X1 = Readonly<Person> // X1 的type为 { readonly name: string; readonly age: number; }
type X2 = Partial<Person> // X2 的type为 { name?: string | undefined; age?: number | undefined; }
type X3 = Required<Person> // X3 的type为 { name: string; age: number; } 去除参数的 ?号
type X4 = Record<string, number>
type X5 = Pick<Person, 'name'> // X5 的type为 { name: string; }
type X6 = Omit<Person, 'name'> // X6 的type为 { age: number; }
type X7 = Exclude<'a' | 'b' | 'c', 'a'> // X7 的type为 'b' | 'c'
type X8 = Extract<'a' | 'b' | 'c', 'a' | 'd'> // X8 的type为 'a'
type X9 = NonNullable<string | number | undefined> // X9 的type为 string | number
type X10 = Parameters<(a: number, b: string) => void> // X10 的type为 [number, string]
type X11 = ConstructorParameters<new (a: number, b: string) => void> // X11 的type为 [number, string]
type X12 = ReturnType<() => string> // X12 的type为 string 返回值类型
// 自己实现
type Readonly<T> = {
readonly [K in keyof T]: T[K]
}
type Partial<T> = {
[K in keyof T]?: T[K]
}
type Required<T> = {
// 减号表示去除 去除参数的 ?号
[K in keyof T]-?: T[K]
}
type Record<K extends keyof string | number | symbol, V> = {
[key in K]: V
}
type Exclude<T, U> = T extends U ? never : T
type Extract<T, U> = T extends U ? T : never
type Omit<T,K> = {
[key in keyof T as key extends K ? never : key]: T[key]
}
type Omit<T, K> = Pick<T, Exclude<keyof T, K>>
Readonly的反向操作
type Person = { readonly name: string, readonly age: number }
// 去除 readonly
type Mutable<T> = {
-readonly [K in keyof T]: T[K]
}
type Result = Mutable<Person> // Result 的type为 { name: string; age: number; }