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️⃣ 基本用法
      • 2️⃣ 常见使用场景
        • ✅ 场景 1:配置对象 → 类型自动同步
        • ✅ 场景 2:函数 / hook 返回值类型
      • 1️⃣ 基本用法
      • 2️⃣ keyof 的实际价值
        • ✅ 限制参数只能是对象的 key
      • 1️⃣ 从“对象值”中拿 key
      • 2️⃣ 替代 enum(前端强烈推荐)
      • ❌ 没有 as const
      • ✅ 使用 as const
        • 1️⃣ keyof any
        • 2️⃣ keyof + 映射类型
      • 1️⃣ React props 校验
      • 2️⃣ Vue emit 事件
      • 3️⃣ 表单字段约束
    • 映射类型
    • extends的约束、条件、分发
    • infer关键字(TS的灵魂)
  • 《TypeScript》学习笔记
  • 实践应用
mamingjuan
2020-12-05
目录

keyof和typeof

# 一、typeof(在 TS 里是“取类型”)

⚠️ TS 的 typeof ≠ JS 的 typeof

场景 JS typeof TS typeof
作用 运行时 编译期
返回 字符串 类型

# 1️⃣ 基本用法

const user = {
  id: 1,
  name: 'Tom',
  age: 18
}

type User = typeof user
1
2
3
4
5
6
7

等价于:

type User = {
  id: number
  name: string
  age: number
}
1
2
3
4
5

📌 核心用途:从“值”反推“类型”


# 2️⃣ 常见使用场景

# ✅ 场景 1:配置对象 → 类型自动同步

const config = {
  mode: 'dark',
  size: 'small'
}

type Config = typeof config
1
2
3
4
5
6

你改 config,类型自动变,不会不同步 👍


# ✅ 场景 2:函数 / hook 返回值类型

function useUser() {
  return {
    name: 'Tom',
    age: 18
  }
}

type User = ReturnType<typeof useUser>
1
2
3
4
5
6
7
8

(typeof + 工具类型是王炸)


# 二、keyof(取对象的 key)

# 1️⃣ 基本用法

type User = {
  id: number
  name: string
  age: number
}

type UserKeys = keyof User
1
2
3
4
5
6
7

结果:

type UserKeys = 'id' | 'name' | 'age'
1

📌 keyof = 把 key 变成联合类型


# 2️⃣ keyof 的实际价值

# ✅ 限制参数只能是对象的 key

function getValue<T, K extends keyof T>(obj: T, key: K) {
  return obj[key]
}

getValue(user, 'name') // ✅
getValue(user, 'xxx')  // ❌
1
2
3
4
5
6

这是 TS 类型安全的核心能力之一。


# 三、typeof + keyof(组合拳)

# 1️⃣ 从“对象值”中拿 key

const user = {
  id: 1,
  name: 'Tom',
  age: 18
}

type UserKeys = keyof typeof user
1
2
3
4
5
6
7

结果:

'id' | 'name' | 'age'
1

📌 这是最常见的写法


# 2️⃣ 替代 enum(前端强烈推荐)

const STATUS = {
  PENDING: 'pending',
  SUCCESS: 'success',
  ERROR: 'error'
} as const

type Status = typeof STATUS[keyof typeof STATUS]
1
2
3
4
5
6
7

结果:

type Status = 'pending' | 'success' | 'error'
1

💥 Vue / React 状态管理标配写法


# 四、进阶:as const 的重要性(必懂)

# ❌ 没有 as const

const user = {
  role: 'admin'
}

type Role = typeof user.role
// string ❌
1
2
3
4
5
6

# ✅ 使用 as const

const user = {
  role: 'admin'
} as const

type Role = typeof user.role
// 'admin' ✅
1
2
3
4
5
6

📌 结论:

想拿「字面量类型」,一定要 as const


# 五、keyof 的常见变体

# 1️⃣ keyof any

type Keys = keyof any
// string | number | symbol
1
2

# 2️⃣ keyof + 映射类型

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

这是 Readonly<T> 的底层原理。


# 六、真实前端场景示例

# 1️⃣ React props 校验

const props = {
  size: 'small',
  type: 'primary'
} as const

type Props = typeof props
type PropKeys = keyof Props
1
2
3
4
5
6
7

# 2️⃣ Vue emit 事件

const emits = {
  submit: (value: string) => true,
  cancel: () => true
}

type EmitName = keyof typeof emits
// 'submit' | 'cancel'
1
2
3
4
5
6
7

# 3️⃣ 表单字段约束

type Form = {
  username: string
  password: string
}

function updateField(key: keyof Form, value: string) {}
1
2
3
4
5
6

# 七、常见坑总结(面试必问)

❌ keyof 用在值上

keyof user // ❌
keyof typeof user // ✅
1
2

❌ typeof 不能用在类型上

type A = { a: number }
type B = typeof A // ❌
1
2

❌ 忘了 as const

const arr = ['a', 'b']
type A = typeof arr[number] // string ❌
1
2
const arr = ['a', 'b'] as const
type A = typeof arr[number] // 'a' | 'b' ✅
1
2

# 八、一句话记忆法 🧠

  • typeof:从值 → 类型
  • keyof:从类型 → key 联合
  • typeof + keyof:从对象 → key 联合
上次更新: 2026/01/07, 09:20:46
null和undefined
映射类型

← null和undefined 映射类型→

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