映射类型(Mapped Types)是 TypeScript 中的一种高级类型,它允许你基于现有类型创建新的类型。通过映射类型,你可以对现有类型的属性进行转换、添加或删除,从而生成新的类型。映射类型通常与泛型一起使用,提供了一种灵活的方式来操作和转换类型。
映射类型的基本语法
映射类型的基本语法如下:
{ [P in K]: T }
其中:
P
是一个类型变量,表示属性名。
K
是一个联合类型,表示一组属性名。
T
是一个类型表达式,表示属性的类型。
示例
以下是一个简单的映射类型示例,展示了如何将一个对象类型的所有属性转换为只读属性:
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
interface Person {
name: string;
age: number;
}
type ReadonlyPerson = Readonly<Person>;
const person: ReadonlyPerson = {
name: "Alice",
age: 25
};
person.name = "Bob"; // Error: Cannot assign to 'name' because it is a read-only property.
在这个例子中,Readonly
是一个映射类型,它将 Person
接口的所有属性转换为只读属性。
常见的映射类型
TypeScript 提供了一些内置的映射类型,常见的有:
Readonly<T>
:将 T
的所有属性设置为只读。
Partial<T>
:将 T
的所有属性设置为可选。
Required<T>
:将 T
的所有可选属性设置为必选。
Pick<T, K>
:从 T
中选择一组属性 K
来创建新类型。
Record<K, T>
:创建一个类型,其属性名为 K
中的每个成员,属性类型为 T
。
1. Readonly<T>
将 T
的所有属性设置为只读。
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
2. Partial<T>
将 T
的所有属性设置为可选。
type Partial<T> = {
[P in keyof T]?: T[P];
};
3. Required<T>
将 T
的所有可选属性设置为必选。
type Required<T> = {
[P in keyof T]-?: T[P];
};
4. Pick<T, K>
从 T
中选择一组属性 K
来创建新类型。
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
5. Record<K, T>
创建一个类型,其属性名为 K
中的每个成员,属性类型为 T
。
type Record<K extends keyof any, T> = {
[P in K]: T;
};
自定义映射类型
除了使用内置的映射类型,你还可以自定义映射类型来满足特定的需求。
示例
以下是一个自定义映射类型示例,展示了如何将一个对象类型的所有属性转换为 nullable
类型:
type Nullable<T> = {
[P in keyof T]: T[P] | null;
};
interface Person {
name: string;
age: number;
}
type NullablePerson = Nullable<Person>;
const person: NullablePerson = {
name: "Alice",
age: null
};
在这个例子中,Nullable
是一个自定义映射类型,它将 Person
接口的所有属性转换为 nullable
类型。
映射类型的实际应用
1. 动态生成类型
映射类型可以用于动态生成类型,例如根据配置对象生成对应的类型:
interface Config {
featureA: boolean;
featureB: boolean;
featureC: boolean;
}
type FeatureFlags = {
[P in keyof Config as `enable${Capitalize<P>}`]: Config[P];
};
const flags: FeatureFlags = {
enableFeatureA: true,
enableFeatureB: false,
enableFeatureC: true
};
在这个例子中,FeatureFlags
是一个映射类型,它根据 Config
接口动态生成了新的类型。
2. 类型转换
映射类型可以用于类型转换,例如将对象类型的所有属性转换为函数类型:
type FunctionProperties<T> = {
[P in keyof T]: T[P] extends (...args: any[]) => any ? T[P] : never;
};
interface Person {
name: string;
greet(): string;
}
type PersonFunctions = FunctionProperties<Person>;
const personFunctions: PersonFunctions = {
name: "Alice", // Error: Type 'string' is not assignable to type 'never'.
greet() {
return "Hello, world!";
}
};
在这个例子中,FunctionProperties
是一个映射类型,它将 Person
接口的所有属性转换为函数类型。
总结
映射类型是 TypeScript 中用于基于现有类型创建新类型的强大工具。通过映射类型,你可以对现有类型的属性进行转换、添加或删除,从而生成新的类型。理解映射类型的使用场景和语法,可以帮助你编写出更灵活和类型安全的代码。