运算符 keyof 和 typeof 是 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) { /* ... */ }
优点:
缺点: