TypeScript映射类型 #
一、映射类型基础 #
1.1 什么是映射类型 #
映射类型建立在索引签名的语法之上,用于创建新类型,新类型基于旧类型的每个属性。
typescript
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
interface User {
name: string;
age: number;
}
type ReadonlyUser = Readonly<User>;
1.2 基本语法 #
typescript
type Mapped<T> = {
[P in keyof T]: T[P];
};
1.3 keyof操作符 #
keyof获取类型的所有键的联合类型:
typescript
interface User {
name: string;
age: number;
}
type UserKeys = keyof User;
二、内置映射类型 #
2.1 Partial #
将所有属性变为可选:
typescript
type Partial<T> = {
[P in keyof T]?: T[P];
};
interface User {
name: string;
age: number;
}
type PartialUser = Partial<User>;
const user: PartialUser = {
name: 'Alice'
};
2.2 Required #
将所有属性变为必需:
typescript
type Required<T> = {
[P in keyof T]-?: T[P];
};
interface User {
name: string;
age?: number;
}
type RequiredUser = Required<User>;
const user: RequiredUser = {
name: 'Alice',
age: 25
};
2.3 Readonly #
将所有属性变为只读:
typescript
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
interface User {
name: string;
age: number;
}
type ReadonlyUser = Readonly<User>;
const user: ReadonlyUser = {
name: 'Alice',
age: 25
};
user.name = 'Bob';
2.4 Pick #
选择部分属性:
typescript
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
interface User {
id: number;
name: string;
email: string;
}
type UserPreview = Pick<User, 'id' | 'name'>;
const preview: UserPreview = {
id: 1,
name: 'Alice'
};
2.5 Omit #
排除部分属性:
typescript
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
interface User {
id: number;
name: string;
password: string;
}
type PublicUser = Omit<User, 'password'>;
const user: PublicUser = {
id: 1,
name: 'Alice'
};
2.6 Record #
创建对象类型:
typescript
type Record<K extends keyof any, T> = {
[P in K]: T;
};
type UserMap = Record<string, number>;
const map: UserMap = {
'a': 1,
'b': 2
};
三、修饰符 #
3.1 添加修饰符 #
typescript
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
type Optional<T> = {
[P in keyof T]?: T[P];
};
3.2 移除修饰符 #
使用-移除修饰符:
typescript
type Required<T> = {
[P in keyof T]-?: T[P];
};
type Mutable<T> = {
-readonly [P in keyof T]: T[P];
};
3.3 组合使用 #
typescript
type MutableRequired<T> = {
-readonly [P in keyof T]-?: T[P];
};
四、键重映射 #
4.1 as子句 #
TypeScript 4.1引入了as子句用于键重映射:
typescript
type Getters<T> = {
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};
interface Person {
name: string;
age: number;
}
type PersonGetters = Getters<Person>;
4.2 过滤属性 #
typescript
type OnlyStrings<T> = {
[K in keyof T as T[K] extends string ? K : never]: T[K];
};
interface Mixed {
name: string;
age: number;
email: string;
active: boolean;
}
type StringProps = OnlyStrings<Mixed>;
4.3 移除前缀 #
typescript
type RemovePrefix<T, P extends string> = {
[K in keyof T as K extends `${P}${infer Rest}` ? Rest : K]: T[K];
};
interface ApiData {
apiName: string;
apiAge: number;
}
type CleanData = RemovePrefix<ApiData, 'api'>;
五、模板字面量类型 #
5.1 基本用法 #
typescript
type EventName = `on${Capitalize<string>}`;
type ClickEvent = 'onClick';
type FocusEvent = 'onFocus';
5.2 结合映射类型 #
typescript
type EventHandlers<T> = {
[K in keyof T as `on${Capitalize<string & K>}`]: (event: T[K]) => void;
};
interface Events {
click: MouseEvent;
focus: FocusEvent;
}
type Handlers = EventHandlers<Events>;
5.3 内置工具类型 #
typescript
type Greeting = 'hello world';
type Upper = Uppercase<Greeting>;
type Lower = Lowercase<Greeting>;
type Capital = Capitalize<Greeting>;
type Uncapital = Uncapitalize<Greeting>;
六、高级应用 #
6.1 深层映射 #
typescript
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};
type DeepReadonly<T> = {
readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
};
6.2 条件映射 #
typescript
type Nullable<T> = {
[P in keyof T]: T[P] | null;
};
interface User {
name: string;
age: number;
}
type NullableUser = Nullable<User>;
const user: NullableUser = {
name: 'Alice',
age: null
};
6.3 值类型映射 #
typescript
type Stringify<T> = {
[P in keyof T]: string;
};
interface User {
name: string;
age: number;
active: boolean;
}
type StringifiedUser = Stringify<User>;
const user: StringifiedUser = {
name: 'Alice',
age: '25',
active: 'true'
};
6.4 类型转换 #
typescript
type Functionize<T> = {
[P in keyof T]: () => T[P];
};
interface User {
name: string;
age: number;
}
type LazyUser = Functionize<User>;
const lazyUser: LazyUser = {
name: () => 'Alice',
age: () => 25
};
七、实用示例 #
7.1 类型安全的get/set #
typescript
type Getters<T> = {
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};
type Setters<T> = {
[K in keyof T as `set${Capitalize<string & K>}`]: (value: T[K]) => void;
};
interface User {
name: string;
age: number;
}
type UserGetters = Getters<User>;
type UserSetters = Setters<User>;
7.2 代理类型 #
typescript
type Proxy<T> = {
[K in keyof T]: {
get(): T[K];
set(value: T[K]): void;
};
};
interface User {
name: string;
age: number;
}
type UserProxy = Proxy<User>;
7.3 验证类型 #
typescript
type Validators<T> = {
[K in keyof T as `${string & K}Validator`]: (value: T[K]) => boolean;
};
interface User {
name: string;
age: number;
}
type UserValidators = Validators<User>;
八、总结 #
本章介绍了TypeScript映射类型:
映射类型基础 #
- keyof操作符
- 索引签名语法
- 属性映射
内置映射类型 #
- Partial
- Required
- Readonly
- Pick
- Omit
- Record
高级特性 #
- 修饰符操作
- 键重映射
- 模板字面量类型
最后更新:2026-03-26