TypeScript如何优化通过变量获取对象属性类型的实现?
方案1:编译期类型安全(推荐)
先通过TS模板字面量类型提取所有合法的feature名,从入参层面就限制输入范围,完全不需要类型断言:
// 提取所有`feature_`开头属性的后缀作为合法入参类型 type FeatureFlag = keyof IGlobals extends `feature_${infer F}` ? F : never function useFeature(feature: FeatureFlag): boolean { const featureKey = `feature_${feature}` as const // 此处TS可以自动推断featureKey是IGlobals上的boolean类型属性,无需断言 return globals[featureKey] }
这个方案的优势:
- 调用时IDE会自动补全合法的feature名(foo/bar),输入非法值会直接编译报错
- 完全没有类型断言,类型100%安全
- 运行时不需要额外判断,性能更好
方案2:兼容动态feature名(运行时校验)
如果你的业务场景需要传入编译期不确定的动态feature名,可以用类型守卫实现类型收缩,同样不需要as boolean断言:
// 提取IGlobals上所有`feature_`开头的属性名 type FeatureKey = Extract<keyof IGlobals, `feature_${string}`> // 类型守卫:校验传入的key是否是合法的feature属性 function isFeatureKey(key: string): key is FeatureKey { return key.startsWith('feature_') && globals.hasOwnProperty(key) } function useFeature(feature: string): boolean { const featureKey = `feature_${feature}` if (isFeatureKey(featureKey)) { // 经过类型守卫收缩后,TS已经确认globals[featureKey]是boolean类型 return globals[featureKey] } return false }
这个方案的优势:
- 支持动态传入任意字符串作为feature名
- 没有硬编码的类型断言,通过类型守卫实现类型自动收缩
- 运行时校验逻辑更严谨,避免隐式错误
原理解释
你提到的lookup类型(索引访问类型)在这里配合条件类型、模板字面量类型使用:
- 首先通过
Extract<keyof IGlobals,feature_${string}>筛选出IGlobals中所有前缀为feature_的属性名,这些属性的类型天然都是boolean,不需要额外断言 - 第一种方案通过
infer关键字提取属性名的后缀作为入参类型,从源头避免非法输入 - 第二种方案通过自定义类型守卫,让TS可以在运行时判断逻辑分支中自动识别变量类型,不需要人工做类型断言
内容的提问来源于stack exchange,提问作者publicJorn
相关产品推荐
相关产品推荐

