工具类型实现
内置类型
Partial<T>
// example
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"
});
// implement
type Partial<T> = {
[P in keyof T]?: T[P]
}
Required<T>
type Required<T> = {
[P in keyof T]-?: T[P]
}
Readonly<T>
type Readonly<T> = {
readonly [P in keyof T]: T[P]
}
Pick<T, K>
// example
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview = Pick<Todo, "title" | "completed">;
const todo: TodoPreview = {
title: "Clean room",
completed: false
};
// implement
type Pick<T, K extends keyof T> = {
[P in K]: T[P]
}
Omit<T, K>
// example
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview = Omit<Todo, "description">;
const todo: TodoPreview = {
title: "Clean room",
completed: false
};
// implement
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
// or
type Omit<T, K> = {
[P in Exclude<keyof T, K>]: T[P]
}
Extract<T, U>
type Extract<T, K> = T extends K ? T : never
Exclude<T, U>
// example
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
// implement
// extends搭配 ?: 运算符使用
type Exclude<T, U> = T extends U ? never : T;
// 相当于: type A = 'a'
type A = Exclude<'x' | 'a', 'x' | 'y' | 'z'>
Record<K, T>
type Record<K extends keyof any, T> = {
[P in K]: T
}
NonNullable<T>
type NonNullable<T extends keyof any> = T extends null | undefined ? never : T
Parameters<T>
// infer 关键字
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
ReturnType<T>
// infer 关键字
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : never