Glittering's blog Glittering's blog
Home
  • 学习手册

    • 《JavaScript教程》
    • 《TypeScript教程》
    • 《Git》
    • 《Vite》
    • 《Vue3》
    • 《React18》
    • 《CSS》
    • 《Tailwind CSS》
    • 《ES6 教程》
    • 《TypeScript 从零实现 axios》
  • 技术文档
  • 算法
  • 工作总结
  • 实用技巧
  • collect
About
  • Classification
  • Label
GitHub (opens new window)

Glitz Ma

前端开发工程师
Home
  • 学习手册

    • 《JavaScript教程》
    • 《TypeScript教程》
    • 《Git》
    • 《Vite》
    • 《Vue3》
    • 《React18》
    • 《CSS》
    • 《Tailwind CSS》
    • 《ES6 教程》
    • 《TypeScript 从零实现 axios》
  • 技术文档
  • 算法
  • 工作总结
  • 实用技巧
  • collect
About
  • Classification
  • Label
GitHub (opens new window)
  • 数据类型

  • 实践应用

    • keyof和typeof
    • 映射类型
      • 一、什么是「映射类型」?
      • 二、最基础示例(一定要会)
        • 1️⃣ 手写 Readonly<T>
        • 2️⃣ 手写 Partial<T>
        • 3️⃣ 手写 Required<T>
      • 三、映射类型中的「修饰符」
        • 修饰符一览
        • 示例:去掉 readonly
      • 四、映射 + 条件判断(进阶)
        • 1️⃣ 根据 key 过滤字段(核心技巧)
        • 2️⃣ key 重命名(Vue / React 源码常见)
      • 五、in 的本质理解(非常重要)
      • 六、真实前端场景
        • 1️⃣ 表单校验规则
        • 2️⃣ Vue props 默认值
        • 3️⃣ API 状态映射
      • 七、常见误区(面试高频)
      • 八、映射类型 = TS 工具类型的底层
      • 九、记忆公式 🧠
    • extends的约束、条件、分发
    • infer关键字(TS的灵魂)
  • 《TypeScript》学习笔记
  • 实践应用
mamingjuan
2020-12-06
目录

映射类型

# 一、什么是「映射类型」?

一句话定义:

用一个已有类型的 key,批量生成一个新类型

核心语法:

type NewType<T> = {
  [K in keyof T]: T[K]
}
1
2
3

📌 这里的 in 不是 JS 的 in,而是 类型层面的遍历 key


# 二、最基础示例(一定要会)

# 1️⃣ 手写 Readonly<T>

type MyReadonly<T> = {
  readonly [K in keyof T]: T[K]
}
1
2
3

等价于 TS 内置的:

Readonly<T>
1

# 2️⃣ 手写 Partial<T>

type MyPartial<T> = {
  [K in keyof T]?: T[K]
}
1
2
3

# 3️⃣ 手写 Required<T>

type MyRequired<T> = {
  [K in keyof T]-?: T[K]
}
1
2
3

📌 -? 表示 移除可选修饰符


# 三、映射类型中的「修饰符」

# 修饰符一览

修饰符 含义
readonly 只读
? 可选
-readonly 移除只读
-? 移除可选

# 示例:去掉 readonly

type Mutable<T> = {
  -readonly [K in keyof T]: T[K]
}
1
2
3

# 四、映射 + 条件判断(进阶)

# 1️⃣ 根据 key 过滤字段(核心技巧)

type FilterString<T> = {
  [K in keyof T as T[K] extends string ? K : never]: T[K]
}
1
2
3
type User = {
  id: number
  name: string
  age: number
}

type StringProps = FilterString<User>
// { name: string }
1
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
type State = {
  count: number
  name: string
}
1
2
3
4

结果:

{
  getCount: () => number
  getName: () => string
}
1
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

# 六、真实前端场景

# 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️⃣ Vue props 默认值

type Props = {
  size: string
  disabled: boolean
}

type DefaultProps = {
  [K in keyof Props]?: Props[K]
}
1
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

# 七、常见误区(面试高频)

❌ in 只能用在类型里

[K in arr] // ❌
1

❌ 忘记 keyof

[K in T] // ❌
[K in keyof T] // ✅
1
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
keyof和typeof
extends的约束、条件、分发

← keyof和typeof extends的约束、条件、分发→

Copyright © 2015-2026 Glitz Ma
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式