Partial<T>
Partial
用于将类型中全部属性变为可选类型:typescript
interface Todo {
title: string;
description: string;
}
const todo1: Todo = {
title: "organize desk",
description: "clear clutter",
};
const todo2: Partial<Todo> = {
description: "throw out trash",
};
复制代码
实现源码:函数
type Partial<T> = {
[P in keyof T]?: T[P];
};
复制代码
Required<T>
Required
用于将类型全部属性变为必需类型:ui
interface Props {
a?: number;
b?: string;
}
const obj: Props = { a: 5 }; // OK
const obj2: Required<Props> = { a: 5 }; // Error: property 'b' missing
复制代码
实现源码:this
type Required<T> = {
[P in keyof T]-?: T[P];
};
复制代码
Readonly<T>
Readonly
用于将类型中全部属性变成只读类型:spa
interface Todo {
title: string;
}
const todo: Readonly<Todo> = {
title: "Delete inactive users"
};
todo.title = "Hello"; // Error: cannot reassign a readonly property
复制代码
实现源码:code
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
复制代码
Record<T, K>
Record
用于将T
中全部的属性转换为K
类型:接口
interface PageInfo {
title: string;
}
type Page = "home" | "about" | "contact";
const x: Record<Page, PageInfo> = {
about: { title: "about" },
contact: { title: "contact" },
home: { title: "home" },
};
复制代码
实现源码:ip
type Record<K extends keyof any, T> = {
[P in K]: T;
};
复制代码
Exclude<T, K>
Exclude
用于筛选全部在T
中,但不在K
中的属性:ci
type T0 = Exclude<"a" | "b" | "c", "a">; // "b" | "c"
type T1 = Exclude<"a" | "b" | "c", "a" | "b">; // "c"
type T2 = Exclude<string | number | (() => void), Function>; // string | number 复制代码
实现源码:源码
type Exclude<T, U> = T extends U ? never : T;
复制代码
Extract<T, K>
Extract
和Exclude
有些相似,用于筛选既在T
中,又在K
中的属性:
type T0 = Extract<"a" | "b" | "c", "a" | "f">; // "a"
type T1 = Extract<string | number | (() => void), Function>; // () => void
复制代码
实现源码:
type Extract<T, U> = T extends U ? T : never;
复制代码
Pick<T, K>
Pick
用于返回从T
中筛选出K
包含的属性所组成的类型:
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview = Pick<Todo, "title" | "completed">;
const todo: TodoPreview = {
title: "Clean room",
completed: false,
};
复制代码
实现源码:
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
复制代码
Omit<T, K>
和Pick
相反,忽略K
中包含的属性:
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview = Omit<Todo, "description">;
const todo: TodoPreview = {
title: "Clean room",
completed: false
};
复制代码
实现源码:
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
复制代码
能够看到,Omit
类型就是对以前提到的Pick
和Exclude
的进一步封装。
NonNullable<T>
NonNullable
用于筛选出T
中不是null
或者undefined
的全部类型:
type T0 = NonNullable<string | number | undefined>; // string | number
type T1 = NonNullable<string[] | null | undefined>; // string[]
复制代码
实现源码:
type NonNullable<T> = T extends null | undefined ? never : T;
复制代码
Parameters<T>
Parameters
用于筛选函数全部的参数类型,并返回一个由这些参数类型构成的元组:
type T0 = Parameters<() => string>; // []
type T1 = Parameters<(s: string) => void>; // [string]
type T2 = Parameters<<T>(arg: T) => T>; // [unknown]
复制代码
实现源码:
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
复制代码
能够看到T
被约束必须为函数类型,若是传入一个非函数类型会报错。
ReturnType<T>
ReturnType
用于获取函数返回值类型:
type T0 = ReturnType<() => string>; // string
type T1 = ReturnType<(s: string) => void>; // void
type T2 = ReturnType<<T>() => T>; // unknown
type T3 = ReturnType<<T extends U, U extends number[]>() => T>; // number[]
复制代码
实现源码:
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
复制代码
T
一样被约束必须为函数类型。
ConstructorParameters<T>
ConstructorParameters
和Parameters
十分类似,用于获取构造函数的全部参数类型:
class Person {
constructor(name: string, age: number) {}
}
type T0 = ConstructorParameters<typeof Person>; // [string, number]
复制代码
实现源码:
type ConstructorParameters<T extends new (...args: any) => any> = T extends new (...args: infer P) => any ? P : never;
复制代码
T
被约束为必须为构造函数。
InstanceType<T>
InstanceType
用于获取构造函数的返回值:
class Person {
constructor(name: string, age: number) {}
}
type T0 = InstanceType<typeof Person>; // Person
复制代码
实现源码:
type InstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer R ? R : any;
复制代码
T
一样被约束为必须为构造函数。
ThisParameterType<T>
ThisParameterType
用于获取函数的this
参数类型。若是函数未指定this
参数,返回unknown
,须要开启strictFunctionTypes
才能工做:
function toHex(this: Number) {
return this.toString(16);
}
type T0 = ThisParameterType<typeof toHex>; // Number
复制代码
实现源码:
type ThisParameterType<T> = T extends (this: infer U, ...args: any[]) => any
? U
: unknown;
复制代码
OmitThisParameter<T>
OmitThisParameter
用于删除函数中的this
参数,须要开启strictFunctionTypes
才能工做:
function toHex(this: Number, others: any) {
return this.toString(16);
}
type T0 = typeof toHex; // function toHex(this: Number, others: any): string
type T1 = OmitThisParameter<typeof toHex>; // (others: any) => string
复制代码
实现源码:
type OmitThisParameter<T> = unknown extends ThisParameterType<T>
? T
: T extends (...args: infer A) => infer R
? (...args: A) => R
: T;
复制代码
ThisType<T>
ThisType
并不会转换类型,而是用于标记函数中this
的类型,相似于指定this
参数。须要开启noImplicitThis
才能工做:
type ObjectDescriptor<D, M> = {
data?: D;
methods?: M & ThisType<D & M>; // 标记方法的this类型
};
function makeObject<D, M>(desc: ObjectDescriptor<D, M>): D & M {
let data: object = desc.data || {};
let methods: object = desc.methods || {};
return { ...data, ...methods } as D & M;
}
let obj = makeObject({
data: { x: 0, y: 0 },
methods: {
moveBy(dx: number, dy: number) {
this.x += dx; // ts能识别this类型
this.y += dy;
}
}
});
复制代码
methods
使用ThisType
指定this
。因此makeObject
函数调用时,ts就能推断出methods
中的函数this
类型为{ x: number, y: number } & { moveBy(dx: number, dy: number): number }
。
在源码中,ThisType
就是一个空的泛型接口。