状态: 初稿
介绍
TypeScript 为你提供许多用于常用类型转换的实用类型. 这些工具全局可用.
Partial<T>
构建一个新类型, 把所有类型为 T
的属性设为”可选”. 该工具返回一个代表给定类型所有子类型的类型.
实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 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', });
|
Readonly<T>
构建一个类型, 把所有类型为 T
的属性设为 readonly
, 表示结果类型的属性不可重赋值.
实例
1 2 3 4 5 6 7 8 9
| interface Todo { title: string; }
const todo: Readonly<Todo> = { title: 'Delete inactive users', };
todo.title = 'Hello';
|
Object.freeze
1
| function freeze<T>(obj: T): Readonly<T>;
|
Record<K,T>
构建一个类型, 它有一个类型为 T
的属性组 K
. 这个工具可以把一类型的属性映射为另一类型.
实例
1 2 3 4 5 6 7 8 9 10 11
| interface PageInfo { title: string; }
type Page = 'home' | 'about' | 'contact';
const x: Record<Page, PageInfo> = { about: { title: 'about' }, contact: { title: 'contact' }, home: { title: 'home' }, };
|
Pick<T,K>
实例
1 2 3 4 5 6 7 8 9 10 11 12
| interface Todo { title: string; description: string; completed: boolean; }
type TodoPreview = Pick<Todo, 'title' | 'completed'>;
const todo: TodoPreview = { title: 'Clean room', completed: false, };
|
Omit<T,K>
挑选 T
中所有属性, 然后移除属性组 K
, 构建一个类型.
实例
1 2 3 4 5 6 7 8 9 10 11 12
| interface Todo { title: string; description: string; completed: boolean; }
type TodoPreview = Omit<Todo, 'description'>;
const todo: TodoPreview = { title: 'Clean room', completed: false, };
|
Exclude<T,U>
从 T
排除所有能赋值给 U
的属性, 构建一个类型.
实例
1 2 3
| type T0 = Exclude<"a" | "b" | "c", "a">; type T1 = Exclude<"a" | "b" | "c", "a" | "b">; type T2 = Exclude<string | number | (() => void), Function>;
|
从 T
中提取所有能赋值给 U
的属性, 构建一个类型.
实例
1 2
| type T0 = Extract<"a" | "b" | "c", "a" | "f">; type T1 = Extract<string | number | (() => void), Function>;
|
NonNullable<T>
从 T
中排除所有 null
和 undefined
, 构建一个类型.
实例
1 2
| type T0 = NonNullable<string | number | undefined>; type T1 = NonNullable<string[] | null | undefined>;
|
Parameters<T>
实例
1 2 3 4 5 6 7 8 9
| declare function f1(arg: { a: number, b: string }): void type T0 = Parameters<() => string>; type T1 = Parameters<(s: string) => void>; type T2 = Parameters<(<T>(arg: T) => T)>; type T4 = Parameters<typeof f1>; type T5 = Parameters<any>; type T6 = Parameters<never>; type T7 = Parameters<string>; type T8 = Parameters<Function>;
|
ReturnType<T>
实例
1 2 3 4 5 6 7 8 9 10
| declare function f1(): { a: number, b: string } type T0 = ReturnType<() => string>; type T1 = ReturnType<(s: string) => void>; type T2 = ReturnType<(<T>() => T)>; type T3 = ReturnType<(<T extends U, U extends number[]>() => T)>; type T4 = ReturnType<typeof f1>; type T5 = ReturnType<any>; type T6 = ReturnType<never>; type T7 = ReturnType<string>; type T8 = ReturnType<Function>;
|
InstanceType<T>
构建一个类型, 它由构造器函数类型 T
的实例类型组成.
实例
1 2 3 4 5 6 7 8 9 10
| class C { x = 0; y = 0; }
type T0 = InstanceType<typeof C>; type T1 = InstanceType<any>; type T2 = InstanceType<never>; type T3 = InstanceType<string>; type T4 = InstanceType<Function>;
|
Required<T>
构建一个类型, 把 T
中所有属性设为 “必选”.
实例
1 2 3 4 5 6 7 8
| interface Props { a?: number; b?: string; };
const obj: Props = { a: 5 };
const obj2: Required<Props> = { a: 5 };
|
ThisType<T>
这个工具不返回一个经转换的类型. 相反, 它作为上下文 this
类型的标识. 注意, 要使用这个工具, 必须打开 --noImplicitThis
选项.
实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
type ObjectDescriptor<D, M> = { data?: D; methods?: M & ThisType<D & M>; }
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; this.y += dy; } } });
obj.x = 10; obj.y = 20; obj.moveBy(5, 5);
|
上例中, makeObject
的参数中的 methods
对象有一个包括 ThisType<D & M>
的上下文类型, 因此 methods
对象内方法中的 this
的类型是 { x: number, y: number } & { moveBy(dx: number, dy: number): number }
. 注意 methods
属性的类型是如何同时成为推断方法中 this
类型的目标和源的.
ThisType<T>
标记接口只是一个在 lib.d.ts
声明的空接口. 除了可以在对象字面量的上下文类型中被识别, 它与普通空接口没有区别.