类型的TypeScript联合被解析为类型的交集

时间:2019-08-07 08:13:32

标签: typescript typescript3.0 union-types

我有这个片段

class J {
  constructor(public foo: number) {}
}

class B {
 constructor(public bar: string) {}
}

interface Cache {
 json?: J;
 binary?: B;
}

function test(key: "json" | "binary", data: J | B, obj: Cache) {
  obj[key] = data;
}

如果您在https://www.typescriptlang.org/play/中尝试此代码,则第obj[key] = data;行出现以下错误

  

类型'J | B”不可分配给“ J&B”类型。     类型“ J”不可分配给类型“ J&B”。       属性“ bar”在类型“ J”中缺失,但在类型“ B”中是必需的。

很明显我缺少一些东西,但我不知道是什么。有想法吗?

2 个答案:

答案 0 :(得分:3)

keydata之间没有关系,因此您可以使用test( "json", new B())调用test,并且该分配无效。

如果您对键使用通用类型参数(称为K),并且将data键入为Cache[K],则打字稿将允许分配。 (尽管它仍然不是100%安全的类型,因为K可能是一个联合,并且可能发生与上述相同的问题):

class J {
  constructor(public foo: number) {}
}

class B {
 constructor(public bar: string) {}
}

interface Cache {
 json?: J;
 binary?: B;
}

function test<K extends keyof Cache>(key: K, data: Cache[K], obj: Cache) {
  obj[key] = data;
}

Play

答案 1 :(得分:2)

Typescript不能告诉您您要更新Cache的哪个属性,并且在有疑问时,他认为您尝试插入的值应该能够同时适合两者。其中J | B can't.

您可以稍微更改test函数签名以使用Partial

function test(update: Partial<Cache>, obj: Cache) {
    Object.assign(obj, update);
}

这样,Typescript可以确保您传递的键/值对对于Cache类有效。