编程全栈开发者

在 TypeScript 中,keyof typeof 是什么?它们的组合是如何工作的,实际应用在哪里?

用 Hintsage AI 助手通过面试

答案。

运算符 keyoftypeof 是 TypeScript 中强大的类型工具。它们的结合使用允许动态构建类型,创建安全的函数,并以灵活的方式表达对象结构。

问题背景

在 TypeScript 中,typeof 用于根据变量推导类型,而 keyof 返回对象或类型的所有键的联合。它们联用使得处理动态声明的对象和构建相互关联的类型成为可能。

问题

在没有这些运算符的情况下,处理对象、枚举和映射表时,通常需要手动重复键的字符串在类型和值中,这会导致不同步错误并增加代码维护的复杂性。

解决方案

通过 typeof 从变量值中获取类型,并使用 keyof 构建所有其键的联合类型。最终结果是类型化的自动化。

示例代码:

const ERRORS = { NOT_FOUND: 'Not found', UNAUTHORIZED: 'Unauthorized', SERVER_ERROR: 'Server error', }; // 通过 typeof 获取类型,而通过 keyof 获取对象的所有键 function getErrorMessage(code: keyof typeof ERRORS): string { return ERRORS[code]; }

关键特点:

  • 帮助构建严格相关的键值类型,而无需手动更新。
  • 允许对使用对象键的函数进行类型化。
  • 消除了键和类型之间不同步的问题。

有陷阱的问题。

通过 typeof 获取的对象值能否自动成为联合类型中的键?

不能,typeof 返回的是对象的结构类型,而不是值。要获取值的联合,需要单独获取值类型。

对于枚举,typeof 会返回什么,keyof typeof 对于枚举又会返回什么?

对于枚举,typeof 返回枚举对象的类型(包括两种方向:键值和值键),而 keyof typeof 返回该对象的字符串/数字键的联合。例如:

enum Colors { Red = 'R', Blue = 'B' } type ColorKeys = keyof typeof Colors; // 'Red' | 'Blue'

是否可以通过 keyof typeof 获取具有类型安全的所有可能参数的列表,该函数接受对象的键?

可以,这样你就创建了一个只接受允许键的函数。这可防止在处理对象键时出现错误。

const config = { mode: 'dark', lang: 'ru' }; type ConfigKeys = keyof typeof config; // 'mode' | 'lang' function useConfig(key: ConfigKeys) { // ... }

类型错误和反模式

  • 错误地期待 keyof typeof 可用于数组的值 - 对于数组,它是索引,而不是值。
  • 不理解 typeof 在类型级别上工作,而不是返回运行时值。
  • 应用于未显式声明的类型,这会破坏类型推导。

生活中的例子

负面案例

在 API 状态常量中,手动指定字符串键的类型:

type StatusCodes = 'OK' | 'FAIL' | 'PENDING'; function isKnownStatus(code: StatusCodes) { /* ... */ }

优点:

  • 清楚可见哪些字符串是被允许的。

缺点:

  • 在更新列表时必须手动更改类型;不同步和错误。

正面案例

使用 keyof typeof 自动支持列表:

const STATUS = { OK: 1, FAIL: 0, PENDING: 2 }; type StatusKeys = keyof typeof STATUS; function checkStatus(key: StatusKeys) { /* ... */ }

优点:

  • 增加/删除状态时,类型会自动更新。
  • 没有类型和值之间不同步的问题。

缺点:

  • 处理非常复杂的结构时,理解这些类型需要经验和注意力。