TypeScript中插值字符串类型为何无法索引同键类型的Record?
报错成因
Record<KeysType, ValueType>的核心语义是对象必须包含KeysType覆盖的所有键。你定义的TypeOfKey =chart-${number}|text-${number}``是包含无限种可能值的联合类型(number可以是任意合法数值),你不可能穷举所有chart-*、text-*格式的键来初始化components,本身Report接口的定义就不符合TypeScript的类型规则。- TypeScript对包含无限范围的模板字面量联合类型,不会将其识别为合法的索引签名参数。哪怕你用来索引的变量类型和Record的键类型完全一致,也会触发无法索引的报错。当你把
TypeOfKey改为string类型时,Record<string, ReportComponent>会自动生成合法的字符串索引签名,因此不会报错。
解决方案
方案1:允许components只包含部分键
如果你的业务场景下components不需要覆盖所有TypeOfKey格式的键,只需要存部分匹配格式的键,把Report接口的components定义修改为Partial<Record<TypeOfKey, ReportComponent>>即可,修改后索引访问不会触发报错。
修改后的核心代码示例:
interface Report { components: Partial<Record<TypeOfKey, ReportComponent>>; }
方案2:将键类型改为有限联合
如果你的业务场景下键的取值是可以穷举的,把TypeOfKey改为明确枚举所有可能值的有限联合即可:
type TypeOfKey = 'chart-1' | 'chart-2' | 'text-1' | 'text-2';
这种情况下Record<TypeOfKey, ReportComponent>的语义是可满足的,索引访问也不会报错。
内容的提问来源于stack exchange,提问作者apokryfos
相关产品推荐
相关产品推荐

