我有这个片段
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”中是必需的。
很明显我缺少一些东西,但我不知道是什么。有想法吗?
答案 0 :(得分:3)
key
和data
之间没有关系,因此您可以使用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;
}
答案 1 :(得分:2)
Typescript不能告诉您您要更新Cache
的哪个属性,并且在有疑问时,他认为您尝试插入的值应该能够同时适合两者。其中J | B can't.
您可以稍微更改test
函数签名以使用Partial
function test(update: Partial<Cache>, obj: Cache) {
Object.assign(obj, update);
}
这样,Typescript可以确保您传递的键/值对对于Cache
类有效。