TypeScript中如何安全访问带联合类型的非字面量键对象?
解决方案
问题核心在于:TypeScript无法通过key in obj的检查,推断出动态string类型的key具体对应联合类型中的哪个属性,因此直接索引会触发类型错误。以下是两种无需类型断言的安全访问方式:
方案1:基础类型守卫收窄
通过自定义类型守卫,让TypeScript明确当前对象包含目标key对应的属性:
const obj = { a: 1 } as { a: number } | { b: number }; const key = "a" as string; // 自定义类型守卫,判断对象是否包含指定key function hasKey<O extends object, K extends string>( obj: O, key: K ): obj is O & Record<K, unknown> { return Object.prototype.hasOwnProperty.call(obj, key); } if (hasKey(obj, key)) { // 此处obj被推断为包含key的对象,obj[key]类型为unknown console.log(obj[key]); }
方案2:精准属性类型推断
如果已知联合类型中所有属性的类型都是number,可以优化类型守卫,直接推断出属性的具体类型:
const obj = { a: 1 } as { a: number } | { b: number }; const key = "a" as string; // 类型守卫同时验证属性类型为number function hasNumberProperty<O extends object, K extends string>( obj: O, key: K ): obj is O & Record<K, number> { return key in obj && typeof (obj as Record<K, unknown>)[key] === "number"; } if (hasNumberProperty(obj, key)) { // 此处obj[key]类型为number console.log(obj[key]); }
两种方式均借助TypeScript的类型守卫机制实现安全推断,适配动态key的场景。
内容的提问来源于stack exchange,提问作者Lumin
相关产品推荐
相关产品推荐

