如何编写TypeScript类型守卫确认Record存在指定键值?
实现
hasNumber类型守卫的方案 你可以通过**类型谓词(Type Predicate)**编写这个类型守卫,同时在运行时验证对象结构与键对应的值类型,让TypeScript能正确推断lookup[key]的类型。以下是具体实现:
type MyAwesomeLookup = Record<string, number> function hasNumber(lookup: unknown, key: string): lookup is MyAwesomeLookup & { [K in typeof key]: number } { // 先判断lookup是有效对象 if (typeof lookup !== 'object' || lookup === null) { return false } // 断言为任意键的对象,避免类型报错 const obj = lookup as Record<string, unknown> // 验证key存在且对应值为number类型 return key in obj && typeof obj[key] === 'number' } // 测试代码 const lookup = { [Math.random().toString()]: 42 } const key = '0.5' if (hasNumber(lookup, key)) { const x: number = lookup[key] console.log({ x }) }
关键说明
- 类型谓词
lookup is MyAwesomeLookup & { [K in typeof key]: number }:当守卫返回true时,TypeScript会明确知晓lookup符合MyAwesomeLookup类型,并且必然包含传入的key,且该键对应的值是number类型,这样就能安全地将lookup[key]赋值给number类型变量。 - 运行时校验:先确认
lookup是不为null的对象,再检查目标key是否存在于对象中,同时验证对应值的类型是否为number,确保类型守卫的准确性。
如果你的lookup已经提前标注为MyAwesomeLookup类型,也可以简化守卫的参数类型:
function hasNumber(lookup: MyAwesomeLookup, key: string): lookup is MyAwesomeLookup & { [K in typeof key]: number } { return key in lookup && typeof lookup[key] === 'number' } const lookup: MyAwesomeLookup = { [Math.random().toString()]: 42 } const key = '0.5' if (hasNumber(lookup, key)) { const x: number = lookup[key] console.log({ x }) }
内容的提问来源于stack exchange,提问作者mzedeler
相关产品推荐
相关产品推荐

