使用可索引签名约束类型时赋值操作失败问题咨询
TypeScript泛型索引赋值报错的原因及解决办法
这不是TypeScript的Bug,是泛型约束的类型检查逻辑导致的设计行为。
原因分析
T extends IndexableByString表示T可以是比IndexableByString更具体的类型。比如假设T是{ name: string; age: number },它符合IndexableByString的约束,但如果用任意string类型的key(比如'address')去赋值,就会破坏T的原有类型结构。
TypeScript在读取操作target[key]时,因为IndexableByString明确允许string索引,所以可以通过检查;但在赋值时,会严格校验泛型T的具体类型,防止给非预期的键赋值,因此抛出错误。
解决方法
有几种方式可以处理这个问题,根据你的需求选择:
类型断言跳过检查
如果确定赋值操作是安全的,可以直接将target断言为IndexableByString:type IndexableByString = { [k: string]: any }; function test<T extends IndexableByString>(target: T, key: string) { var prop = target[key]; (target as IndexableByString)[key] = prop; }调整泛型约束为更宽松的索引类型
使用Record<string, any>代替自定义的IndexableByString,明确约束T支持任意string键的读写:function test<T extends Record<string, any>>(target: T, key: string) { var prop = target[key]; target[key] = prop; // 正常通过 }约束key为T的键类型
如果只允许对T已有的键进行赋值,可以将key的类型改为keyof T,保证操作的类型安全:type IndexableByString = { [k: string]: any }; function test<T extends IndexableByString>(target: T, key: keyof T) { var prop = target[key]; target[key] = prop; // 正常通过 }
内容的提问来源于stack exchange,提问作者RTD
相关产品推荐
相关产品推荐

