# 1. Partial
Partial<T> 的作用就是将某个类型里的属性全部变为可选项 ?。
定义:
// node_modules/typescript/lib/lib.es5.d.ts
/**
* Make all properties in T optional
*/
type Partial<T> = {
[P in keyof T]?: T[P];
};
2
3
4
5
6
7
8
在以上代码中,首先通过 keyof T 拿到 T 的所有属性名,然后使用 in 进行遍历,将值赋给 P,最后通过 T[P] 取得相应的属性值。中间的 ?,用于将所有属性变为可选。
示例:
interface Todo {
title: string;
description: string;
}
function updateTodo(todo: Todo, fieldsToUpdate: Partial<Todo>) {
return { ...todo, ...fieldsToUpdate };
}
const todo1 = {
title: "organize desk",
description: "clear clutter"
};
const todo2 = updateTodo(todo1, {
description: "throw out trash"
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 2. Required
Required 的作用刚好跟 Partial 相反,Partial 是将所有属性改成可选项,Required 则是将所有类型改成必选项。
定义:
// node_modules/typescript/lib/lib.es5.d.ts
/**
* Make all properties in T required
*/
type Required<T> = {
[P in keyof T]-?: T[P];
};
2
3
4
5
6
7
8
以上代码中,-? 的作用就是移除可选项 ?。
与之对应的还有个 +? , 这个含义自然与 -? 之前相反, 它是用来把属性变成可选项的,+ 可省略,见 Partial。
示例:
interface Props {
a?: number;
b?: string;
}
const obj: Props = { a: 5 }; // OK
const obj2: Required<Props> = { a: 5 }; // Error: property 'b' missing
2
3
4
5
6
7
# 3. Readonly
Readonly<T> 的作用是将某个类型所有属性变为只读属性,也就意味着这些属性不能被重新赋值。
定义:
// node_modules/typescript/lib/lib.es5.d.ts
/**
* Make all properties in T readonly
*/
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
2
3
4
5
6
7
8
给子属性添加 readonly 的标识,如果将上面的 readonly 改成 -readonly, 就是移除子属性的 readonly 标识。
示例:
interface Todo {
title: string;
}
const todo: Readonly<Todo> = {
title: "Delete inactive users"
};
todo.title = "Hello"; // Error: cannot reassign a readonly property
2
3
4
5
6
7
8
9
Readonly<T> 对于表示在运行时将赋值失败的表达式很有用(比如,当尝试重新赋值冻结对象的属性时)。
function freeze<T>(obj: T): Readonly<T>;
# 4. Record
Record 的作用是将 K 中所有的属性的值转化为 T 类型。
定义:
// node_modules/typescript/lib/lib.es5.d.ts
/**
* Construct a type with a set of properties K of type T
*/
type Record<K extends keyof any, T> = {
[P in K]: T;
};
2
3
4
5
6
7
8
示例:
Record 通常用于描述一个对key 和 value 类型都有明确约束的对象,比方说,我们要求一个对象的 key 只能为 "home" | "about" | "contact" 其中一种,value 只能为 PageInfo 类型, 那么我们进行如下定义:
interface PageInfo {
title: string;
}
type Page = "home" | "about" | "contact";
const x: Record<Page, PageInfo> = {
about: { title: "about" },
contact: { title: "contact" },
home: { title: "home" }
};
2
3
4
5
6
7
8
9
10
11
# 5. Pick
Pick 的作用是将某个类型中的某些子属性挑出来,变成包含这个类型部分属性的子类型。
定义:
// node_modules/typescript/lib/lib.es5.d.ts
/**
* From T, pick a set of properties whose keys are in the union K
*/
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
2
3
4
5
6
7
8
示例:
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview = Pick<Todo, "title" | "completed">;
const todo: TodoPreview = {
title: "Clean room",
completed: false
};
2
3
4
5
6
7
8
9
10
11
12
# 6. Omit
Omit 的作用刚好跟 Pick 相反,Pick 是从一个类型中挑选出某些类型,而 Omit 则是从一个类型中剔除掉某些类型。
定义:
// node_modules/typescript/lib/lib.es5.d.ts
/**
* Construct a type with the properties of T except for those in type K.
*/
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
2
3
4
5
6
示例:
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview = Omit<Todo, "description">;
const todo: TodoPreview = {
title: "Clean room",
completed: false
};
2
3
4
5
6
7
8
9
10
11
12
# 7. Exclude
Exclude<T, U> 的作用是剔除掉 T 包含在 U 中的元素,换种更加贴近语义的说法就是从 T 中剔除出 U。
定义:
// node_modules/typescript/lib/lib.es5.d.ts
/**
* Exclude from T those types that are assignable to U
*/
type Exclude<T, U> = T extends U ? never : T;
2
3
4
5
6
以上语句的意思就是 如果 T 能赋值给 U 类型的话,那么就会返回 never 类型,否则返回 T,最终结果是将 T 中的某些属于 U 的类型移除掉。
示例:
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
2
3
# 8. Extract
Extract<T, U> 的作用是提取出 T 包含在 U 中的元素,换种更加贴近语义的说法就是从 T 中提取出 U。
定义:
// node_modules/typescript/lib/lib.es5.d.ts
/**
* Extract from T those types that are assignable to U
*/
type Extract<T, U> = T extends U ? T : never;
2
3
4
5
6
以上语句的意思就是 如果 T 能赋值给 U 类型的话,那么就会返回 T 类型,否则返回 never,最终结果是将 T 和 U 中共有的属性提取出来。
示例:
type T01 = Extract<'a' | 'b' | 'c' | 'd', 'a' | 'c' | 'f'>; // -> 'a' | 'c'
可以看到 T 是 'a' | 'b' | 'c' | 'd' ,然后 U 是 'a' | 'c' | 'f' ,返回的新类型就可以将 T 和 U 中共有的属性提取出来,也就是 'a' | 'c' 了。
# 9. NonNullable
NonNullable 的作用是用来过滤类型中的 null 及 undefined 类型。
定义:
// node_modules/typescript/lib/lib.es5.d.ts
/**
* Exclude null and undefined from T
*/
type NonNullable<T> = T extendsnull | undefined ? never : T;
2
3
4
5
6
示例:
type T0 = NonNullable<string | number | undefined>; // string | number
type T1 = NonNullable<string[] | null | undefined>; // string[]
2
# 10. ReturnType
ReturnType 的作用是用于获取函数的返回类型。
定义:
// node_modules/typescript/lib/lib.es5.d.ts
/**
* Obtain the return type of a function type
*/
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
2
3
4
5
6
示例:
type T0 = ReturnType<() =>string>; // string
type T1 = ReturnType<(s: string) =>void>; // void
type T2 = ReturnType<<T>() => T>; // {}
type T3 = ReturnType<<T extends U, U extendsnumber[]>() => T>; // number[]
type T4 = ReturnType<any>; // any
type T5 = ReturnType<never>; // any
type T6 = ReturnType<string>; // Error
type T7 = ReturnType<Function>; // Error
2
3
4
5
6
7
8
# 11. Parameters
Parameters 的作用是用于获得函数的参数类型组成的元组类型。
定义:
// node_modules/typescript/lib/lib.es5.d.ts
/**
* Obtain the parameters of a function type in a tuple
*/
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any
? P : never;
2
3
4
5
6
7
示例:
type A = Parameters<() =>void>; // []
type B = Parameters<typeofArray.isArray>; // [any]
type C = Parameters<typeofparseInt>; // [string, (number | undefined)?]
type D = Parameters<typeofMath.max>; // number[]
2
3
4
# 12. InstanceType
InstanceType 的作用是获取构造函数类型的实例类型。
定义:
// node_modules/typescript/lib/lib.es5.d.ts
/**
* Obtain the return type of a constructor function type
*/
type InstanceType<T extendsnew (...args: any) => any> = T extendsnew (...args: any) => infer R ? R : any;
2
3
4
5
6
示例:
class C {
x = 0;
y = 0;
}
type T0 = InstanceType<typeof C>; // C
type T1 = InstanceType<any>; // any
type T2 = InstanceType<never>; // any
type T3 = InstanceType<string>; // Error
type T4 = InstanceType<Function>; // Error
2
3
4
5
6
7
8
9
10
# 13. ThisType
ThisType<T> 的作用是用于指定上下文对象的类型。
定义:
// node_modules/typescript/lib/lib.es5.d.ts
/**
* Marker for contextual 'this' type
*/
interface ThisType<T> { }
2
3
4
5
6
注意:使用
ThisType<T>时,必须确保--noImplicitThis标志设置为 true。
示例:
interface Person {
name: string;
age: number;
}
const obj: ThisType<Person> = {
dosth() {
this.name // string
}
}
2
3
4
5
6
7
8
9
10
# 14. ConstructorParameters
ConstructorParameters<T> 的作用是提取构造函数类型的所有参数类型。它会生成具有所有参数类型的元组类型(如果 T 不是函数,则返回的是 never 类型)。
定义:
// node_modules/typescript/lib/lib.es5.d.ts
/**
* Obtain the parameters of a constructor function type in a tuple
*/
type ConstructorParameters<T extendsnew (...args: any) => any> = T extendsnew (...args: infer P) => any ? P : never;
2
3
4
5
6
示例:
type A = ConstructorParameters<ErrorConstructor>; // [(string | undefined)?]
type B = ConstructorParameters<FunctionConstructor>; // string[]
type C = ConstructorParameters<RegExpConstructor>; // [string, (string | undefined)?]
2
3