Typescript 严格模式下由联合类型的键进行的不安全字典值赋值

Typescript 严格模式下由联合类型的键进行的不安全字典值赋值,typescript,Typescript,当字典值由联合类型的键指定时,即使使用最新的typescript@3.4.5严格模式 这是一个已知的问题吗?有人能告诉我一个相关的bug报告吗 tsconfig.json { "compilerOptions": { "strict": true } } test.ts 接口A{ a:数字; b:弦; } 接口B{ a:弦; b:数字; } 函数someFunction(a:a,b:b,字段:'a'|'b'):void{ // ... //很多不相关的代码 // ... b[字

当字典值由联合类型的键指定时,即使使用最新的typescript@3.4.5严格模式

这是一个已知的问题吗?有人能告诉我一个相关的bug报告吗

tsconfig.json

{
  "compilerOptions": {
    "strict": true
  }
}
test.ts

接口A{
a:数字;
b:弦;
}
接口B{
a:弦;
b:数字;
}
函数someFunction(a:a,b:b,字段:'a'|'b'):void{
// ...
//很多不相关的代码
// ...
b[字段]=a[字段];
// ...
//很多不相关的代码
// ...
}
常数a={a:1,b:'1'};
常数b={a:'2',b:2};
someFunction(a,b,'a');
//B.a的类型是字符串,但在本例中,分配了一个编号
//即使在严格模式下,TypeScript也无法发出警告:-(
console.log(类型为b['a']);
使用typescript@3.4.5ts节点(
ts node test.ts
)产生


是的,这是不合理的,是一个已知的类型系统中的漏洞,将在3.5中用它来修复。从PR:

通过此PR,我们可以通过多种方式提高索引访问类型的可靠性:

  • 当索引访问
    T[K]
    发生在类型关系的源端时,它将解析为由
    T[K]
    选择的属性的联合类型,但当它发生在类型关系的目标端时,它现在将解析为由
    T[K]选择的属性的交集类型
    。以前,目标端也会解析为联合类型,这是不合理的
  • 当索引访问
    T[K]时,给定带有约束的类型变量
    T
    发生在类型关系的目标端,此时将忽略
    C
    中的索引签名。这是因为
    T
    的类型参数实际上不需要具有索引签名,只需要具有具有匹配类型的属性即可
  • 类型
    {[key:string]:number}
    不再与映射类型
    {[P in K]:number}
    相关,其中
    K
    是一个类型变量。这与源中的字符串索引签名与目标中的实际属性不匹配一致
  • 现在对索引访问类型的约束进行了更深入的研究。例如,给定类型变量
    T
    K扩展了'a'|'b'
    ,类型
    {a:T,b:T}[K]
    T
    现在被认为与以前不相关
注意:突出显示可能与此问题相关的位。
您现在可以在3.5上试用,方法是使用
npm install安装它typescript@next
您将得到预期的错误。

有趣的是,您甚至不需要两个对象来实现这一点,它看起来像一个['a'|'b']是number | string,因此它将允许您为其分配一个数字或字符串,即使我们知道这是不正确的。似乎在分配时,它应该声明值是number&string,而不是number | string?(编辑:哦,看起来他们已经根据下面的答案解决了所有问题,忽略我。)
number