映射类型
# 一、什么是「映射类型」?
一句话定义:
用一个已有类型的 key,批量生成一个新类型
核心语法:
type NewType<T> = {
[K in keyof T]: T[K]
}
1
2
3
2
3
📌 这里的 in 不是 JS 的 in,而是 类型层面的遍历 key
# 二、最基础示例(一定要会)
# 1️⃣ 手写 Readonly<T>
type MyReadonly<T> = {
readonly [K in keyof T]: T[K]
}
1
2
3
2
3
等价于 TS 内置的:
Readonly<T>
1
# 2️⃣ 手写 Partial<T>
type MyPartial<T> = {
[K in keyof T]?: T[K]
}
1
2
3
2
3
# 3️⃣ 手写 Required<T>
type MyRequired<T> = {
[K in keyof T]-?: T[K]
}
1
2
3
2
3
📌 -? 表示 移除可选修饰符
# 三、映射类型中的「修饰符」
# 修饰符一览
| 修饰符 | 含义 |
|---|---|
readonly | 只读 |
? | 可选 |
-readonly | 移除只读 |
-? | 移除可选 |
# 示例:去掉 readonly
type Mutable<T> = {
-readonly [K in keyof T]: T[K]
}
1
2
3
2
3
# 四、映射 + 条件判断(进阶)
# 1️⃣ 根据 key 过滤字段(核心技巧)
type FilterString<T> = {
[K in keyof T as T[K] extends string ? K : never]: T[K]
}
1
2
3
2
3
type User = {
id: number
name: string
age: number
}
type StringProps = FilterString<User>
// { name: string }
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
📌 as 在映射类型里可以改 key
# 2️⃣ key 重命名(Vue / React 源码常见)
type Getters<T> = {
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K]
}
1
2
3
2
3
type State = {
count: number
name: string
}
1
2
3
4
2
3
4
结果:
{
getCount: () => number
getName: () => string
}
1
2
3
4
2
3
4
# 五、in 的本质理解(非常重要)
[K in keyof T]
1
等价于:
K = 'a' | 'b' | 'c'
1
👉 TS 会对 联合类型自动展开
type Keys = 'a' | 'b'
type Obj = {
[K in Keys]: number
}
// { a: number; b: number }
1
2
3
4
5
6
2
3
4
5
6
# 六、真实前端场景
# 1️⃣ 表单校验规则
type Form = {
username: string
password: string
}
type Rules<T> = {
[K in keyof T]: {
required?: boolean
message?: string
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 2️⃣ Vue props 默认值
type Props = {
size: string
disabled: boolean
}
type DefaultProps = {
[K in keyof Props]?: Props[K]
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 3️⃣ API 状态映射
type Api = {
getUser: () => void
getList: () => void
}
type LoadingState<T> = {
[K in keyof T]: boolean
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 七、常见误区(面试高频)
❌ in 只能用在类型里
[K in arr] // ❌
1
❌ 忘记 keyof
[K in T] // ❌
[K in keyof T] // ✅
1
2
2
❌ 以为 in 是运行时
// 映射类型不会生成 JS 代码
1
# 八、映射类型 = TS 工具类型的底层
| 工具类型 | 底层 |
|---|---|
Partial | in + ? |
Required | in + -? |
Readonly | in + readonly |
Pick | in + 条件 |
Record | in |
# 九、记忆公式 🧠
- keyof:拿 key
- in:遍历 key
- as:改 key
- extends:筛 key
上次更新: 2026/01/07, 09:20:46