Typescript 为什么扩展索引泛型不允许赋值? 导出函数blah(b:T,p:string){ b[p].push(3);//有效的类型脚本 b[p]=[];//ts(2536)类型“string”不能用于索引类型“T”。 }

Typescript 为什么扩展索引泛型不允许赋值? 导出函数blah(b:T,p:string){ b[p].push(3);//有效的类型脚本 b[p]=[];//ts(2536)类型“string”不能用于索引类型“T”。 },typescript,generics,Typescript,Generics,文档中是否有一些部分介绍了这种行为,以便我更好地理解它?啊,好的,找到了。具体错误是由于在和中实现的写入索引访问类型时变得更加严格 一般来说,如果编译器不能确定您是否正在向属性写入正确的值类型,它会抱怨。特别是在这种情况下: 给定具有约束的类型变量T,当类型关系的目标端出现索引访问T[K]时,C中的索引签名现在被忽略。这是因为T的类型参数实际上并不需要具有索引签名,它只需要具有具有匹配类型的属性 因此,当我调用blah()时,我可以给出一个实际上没有索引签名的对象: export functio

文档中是否有一些部分介绍了这种行为,以便我更好地理解它?

啊,好的,找到了。具体错误是由于在和中实现的写入索引访问类型时变得更加严格

一般来说,如果编译器不能确定您是否正在向属性写入正确的值类型,它会抱怨。特别是在这种情况下:

给定具有约束的类型变量
T
,当类型关系的目标端出现索引访问
T[K]
时,
C
中的索引签名现在被忽略。这是因为
T
的类型参数实际上并不需要具有索引签名,它只需要具有具有匹配类型的属性

因此,当我调用
blah()
时,我可以给出一个实际上没有索引签名的对象:

export function blah<T extends { [key: string]: number[] }>(b: T, p: string) {
  b[p].push(3); // valid typescript
  b[p] = []; // ts(2536) Type 'string' cannot be used to index type 'T'.
}
因此,编译器可能会担心
b[p]
不存在


有趣的是,这种增加的安全性只在写入属性时发生,而在读取属性时显然并不重要。它仍然允许TS-3.5之前的行为,而且由于索引签名本身不健全(请参阅;它们不会预测可能的
未定义的
值),因此您的
push()
很有可能出现运行时错误


那么,嗯,耶?我想这里的答案是#30769和#13778的组合


哦,好吧,希望这有帮助;祝你好运

谢谢你的回复。您说过“您的
push()
很有可能出现运行时错误。”在什么类型兼容的情况下会发生运行时错误?我猜那里可能有空值,但我正在运行
--strict
等等({a:[]},“oops”)在运行时爆炸,因为
oops
属性是
undefined
。任何时候
p
不是
b
的键,您都会遇到问题。由于microsoft/TypeScript#13778,strict
无法捕捉到这一点
blah({a: []}, "oops"); // no error