TypeScript 工具类型 (Utility Types)
TypeScript 提供了一系列内置的工具类型(Utility Types),它们可以帮助你快速地对现有类型进行转换和操作。这些工具类型不仅简化了常见的类型操作,还提高了代码的可读性和可维护性。以下是 TypeScript 中一些常用的工具类型及其使用场景。
1. Partial<T>
将对象类型 T 的所有属性变为可选。
typescript
interface Todo {
title: string;
description: string;
}
type PartialTodo = Partial<Todo>; // { title?: string; description?: string; }2. Required<T>
将对象类型 T 的所有属性变为必填项。
typescript
interface Todo {
title?: string;
description?: string;
}
type RequiredTodo = Required<Todo>; // { title: string; description: string; }3. Readonly<T>
将对象类型 T 的所有属性变为只读。
typescript
interface Todo {
title: string;
description: string;
}
type ReadonlyTodo = Readonly<Todo>; // { readonly title: string; readonly description: string; }4. Record<K, T>
创建一个新类型,其中键为 K 的联合类型,值为 T。
typescript
type StringKeyedObject = Record<string, number>;
// 等价于:{ [key: string]: number }
const obj: StringKeyedObject = {
one: 1,
two: 2,
};5. Pick<T, K>
从类型 T 中选取指定的键 K,并返回一个新的类型。
typescript
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview = Pick<Todo, "title" | "completed">;
// { title: string; completed: boolean; }6. Omit<T, K>
从类型 T 中移除指定的键 K,并返回一个新的类型。
typescript
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoInfo = Omit<Todo, "completed">;
// { title: string; description: string; }7. Exclude<T, U>
从联合类型 T 中移除与 U 兼容的成员。
typescript
type T0 = Exclude<"a" | "b" | "c", "a">; // "b" | "c"8. Extract<T, U>
从联合类型 T 中提取与 U 兼容的成员。
typescript
type T0 = Extract<"a" | "b" | "c", "a" | "f">; // "a"9. NonNullable<T>
从类型 T 中移除 null 和 undefined。
typescript
type T0 = NonNullable<string | number | undefined | null>; // string | number10. ReturnType<T>
获取函数类型 T 的返回值类型。
typescript
function fn(): { a: number; b: string } {
return { a: 1, b: "hello" };
}
type T0 = ReturnType<typeof fn>; // { a: number; b: string; }11. InstanceType<T>
获取构造函数类型 T 的实例类型。
typescript
class C {
x = 0;
y = 0;
}
type T0 = InstanceType<typeof C>; // C12. Parameters<T>
获取函数类型 T 的参数类型,以元组形式返回。
typescript
function fn(x: string, y: number): void {}
type T0 = Parameters<typeof fn>; // [string, number]13. ConstructorParameters<T>
获取构造函数类型 T 的参数类型,以元组形式返回。
typescript
class C {
constructor(x: string, y: number) {}
}
type T0 = ConstructorParameters<typeof C>; // [string, number]14. ThisParameterType<T> 和 OmitThisParameter<T>
ThisParameterType<T>获取函数类型的this参数类型。OmitThisParameter<T>移除函数类型的this参数。
typescript
function toHex(this: Number) {
return this.toString(16);
}
type T0 = ThisParameterType<typeof toHex>; // Number
type T1 = OmitThisParameter<typeof toHex>; // () => string15. Awaited<T>
递归地展开 Promise 类型,直到得到最终的非 Promise 类型。
typescript
async function fn() {
return "hello";
}
type T0 = Awaited<ReturnType<typeof fn>>; // string实际应用案例
假设我们有一个配置对象,并希望创建一个函数来安全地更新其属性:
typescript
interface Config {
host: string;
port: number;
debug: boolean;
}
function updateConfig<K extends keyof Config>(
config: Config,
key: K,
value: Config[K]
): void {
config[key] = value;
}
const config: Config = {
host: "localhost",
port: 8080,
debug: true,
};
updateConfig(config, "host", "127.0.0.1"); // OK
updateConfig(config, "port", 9000); // OK
updateConfig(config, "debug", false); // OK
// updateConfig(config, "unknown", "value"); // Error, "unknown" is not a valid key of Config在这个例子中:
keyof Config提取了Config接口的所有键。K extends keyof Config确保了key参数只能是Config接口中的有效键。Config[K]使用索引访问类型确保value参数的类型与key对应的属性类型匹配。
总结
TypeScript 的工具类型提供了丰富的功能,用于快速地对现有类型进行转换和操作。通过合理使用这些工具类型,你可以简化常见的类型操作,提高代码的安全性和可维护性。