工具类
typeof
typeof 操作符可以用来获取一个变量或对象的类型。
ts
interface Person {
name: string
age: number
}
const sem: Person = { name: 'semlinker', age: 30 }
type Sem = typeof sem // type Sem = Personts
function toArray(x: number): Array<number> {
return [x]
}
type Func = typeof toArray // -> (x: number) => number[]keyof
ts
interface Todo {
id: number
text: string
done: boolean
}
const todo: Todo = {
id: 1,
text: 'Learn TypeScript keyof',
done: false,
}
function prop<T extends object, K extends keyof T>(obj: T, key: K) {
return obj[key]
}Partial
Partial<Type>类型的作用就是返回一个新类型,这个新类型和目标类型 T 拥有相同的属性,但所有属性都是可选的。
ts
type Partial<T> = {
[P in keyof T]?: T[P];
}Extract<Type, Union>
选取 Type 类型和 Union 类型两者的公共部分并返回为一个新类型,可以理解为取交集。
ts
type Extract<T, U> = T extends U ? T : neverNonNullable<Type>
过滤掉 Type 中的 null 和 undefined,剩余的类型作为一个新类型返回。其实就是 Exclude 的一种特殊情况。
ts
type NonNullable<T> = T extends null | undefined ? never : Ttypescript
// 工具类型
type MaybeNull<T> = T | null
function process13(input: MaybeNull<{ handler: any }>) {
input?.handler()
}
type MaybeArray<T> = T | T[]
function ensureArray13<T>(input: MaybeArray<T>): T[] {
return Array.isArray(input) ? input : [input]
}映射类型
typescript
// 映射类型
type Stringify<T> = {
[K in keyof T]: string;
}
interface Foo {
prop1: string
prop2: number
prop3: boolean
prop4: () => void
}
type StringifiedFoo = Stringify<Foo>
// 等价于
interface StringifiedFooAns {
prop1: string
prop2: string
prop3: string
prop4: string
}
// 等价于
interface StringifiedFooAns2 {
prop1: string
prop2: string
prop3: string
prop4: string
}高级操作:克隆类型
typescript
type Clone<T> = {
[K in keyof T]: T[K];
}IsAny 与 IsUnknown
typescript
// IsAny 与 IsUnknown
type IsAny<T> = 0 extends 1 & T ? true : false
type IsUnknown<T> = unknown extends T
? IsAny<T> extends true
? false
: true
: false属性修饰工具类型
typescript
// 属性修饰工具类型
type Partial<T> = {
[P in keyof T]?: T[P]; // 标记属性可选
}
type Partial_2<T> = {
[P in keyof T]+?: T[P]; // 和上述相等,更好理解,表示在原本的属性上添加可选
}
type Required<T> = {
[P in keyof T]-?: T[P]; // -? 表示原本属性上如果有 ? 这个标记,则移除它
}
type Readonly<T> = {
readonly [P in keyof T]: T[P];
}结构工具类型
Record
typescript
// 内置类型 Record
type Record<K extends keyof any, T> = {
[P in K]: T;
}
// 键名均为字符串,键值类型未知
type Record_1 = Record<string, unknown>
// 键名均为字符串,键值类型任意
type Record_2 = Record<string, any>
// 其中,Record<string, unknown> 和 Record<string, any> 是日常使用较多的形式,通常我们使用这两者来代替 object 。
// 键名为字符串或数字,键值类型任意
type Record_3 = Record<string | number, any>typescript
// 例子:用于字典
interface Dictionary<T> {
[index: string]: T
}
interface NumericDictionary<T> {
[index: number]: T
}Pick
typescript
// 结构处理工具类型 Pick
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
}
// 例子:
interface Foo {
name: string
age: number
isVip: boolean
}
type PickedFoo = Pick<Foo, 'name' | 'age'>Omit
typescript
// Omit 是基于 Pick 实现的,反向工具类型基于正向工具类型实现
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>Exclude<A, B> 的结果就是联合类型 A 中不存在于 B 中的部分,举例:
typescript
type Tmp1 = Exclude<1, 2> // 1
type Tmp2 = Exclude<1 | 2, 2> // 1
type Tmp3 = Exclude<1 | 2 | 3, 2 | 3> // 1
type Tmp4 = Exclude<1 | 2 | 3, 2 | 4> // 1 | 3那么 Exclude<keyof T, K> 其实就是 T 的键名联合类型中剔除了 K 的部分
集合工具类型
typescript
// 交集
type Extract<T, U> = T extends U ? T : never
// 差集
type Exclude<T, U> = T extends U ? never : Ttypescript
// 集合工具类型汇总
// 并集
export type Concurrence<A, B> = A | B
// 交集
export type Intersection<A, B> = A extends B ? A : never
// 差集
export type Difference<A, B> = A extends B ? never : A
// 补集
export type Complement<A, B extends A> = Difference<A, B>typescript
// 例子 集合 T 相对于 null | undefined 的差集
type NonNullable<T> = T extends null | undefined ? never : T
type _NonNullable<T> = Difference<T, null | undefined>模式匹配工具类型
主要使用条件类型与 infer 关键字。
对函数类型签名的模式匹配
typescript
type FunctionType = (...args: any) => any
type Parameters<T extends FunctionType> = T extends (...args: infer P) => any
? P
: never
type ReturnType<T extends FunctionType> = T extends (...args: any) => infer R
? R
: any更进一步,比如只匹配第一个参数类型:
typescript
type Firstparameter<T extends FunctionType> = T extends (
arg: infer P,
...args: any
) => any
? P
: never
type FuncFoo = (args: number) => void
type FooFirstParameter = Firstparameter<FuncFoo> // number
type FuncBar = (...args: string[]) => void
type BarFirstParameter = Firstparameter<FuncBar> // string对 Class 进行模式匹配
typescript
type ClassType = abstract new (...args: any) => any
type ConstructorParameters<T extends ClassType> = T extends abstract new (...args: infer P) => any ? P : never
type InstanceType<T extends ClassType> = T extends abstract new (...args: any) => infer R ? R : neverClass 的通用类型签名,实际上就是声明了可实例化(new)与可抽象(abstract)
typescript
export interface ClassType<TInstanceType = any> {
new (...args: any[]): TInstanceType
}拓展
提取数组第一个成员的工具类型
typescript
type FirstArrayItemType<T extends any[]> = T extends [infer R, ...any[]]
? R
: never
// 加上字符串条件类型
type FirstArrayItemType2<T extends any[]> = T extends [infer R, ...any[]]
? R extends string
? R
: never
: never
type Tmp1 = FirstArrayItemType2<[100, 'Chocolate']> // never
type Tmp2 = FirstArrayItemType2<['Chocolate', 100]> // 'Chocolate'typescript
// ts 4,7 支持 infer 约束功能,能对特定类型进行提取
type FirstArrayItemType3<T extends any[]> = T extends [infer R extends string, ...any[]] ? R : never