【发布时间】:2019-07-12 17:32:27
【问题描述】:
考虑以下 Typescript 类型...
export type Dog = {
color: string,
earsFloppy: boolean,
_type: "dog"
}
export type Fish = {
color: string,
finsFlowy: boolean,
_type: "fish"
}
export type Pet = Dog | Fish;
export type PetMap = {
dog: Dog[],
fish: Fish[]
}
考虑以下函数(也在 Typescript 中)...
var myPetMap = { dog: [], fish: [] };
function addToPetMap(newPet: Pet): void {
myPetMap[newPet._type].push(newPet);
}
我的项目中有几乎相同的设置,但出现以下错误:
[ts] Cannot invoke an expression whose type lacks a call signature. Type '((...items: Dog[]) => number) | ((...items: Fish[]) => number)' has no compatible call signatures. [2349]
但是执行以下操作可以解决问题...
var myPetMap = { dog: [], fish: [] };
function addToPetMap(newPet: Pet): void {
switch(newPet._type) {
case 'dog':
myPetMap[newPet._type].push(newPet);
break;
case 'fish':
myPetMap[newPet._type].push(newPet);
break;
}
}
就好像newPet._type 的值必须在myPetMap[newPet._type].push(newPet) 存在的范围内是已知的或具体的。它不能存在于newPet._type 的值不能保证为dog (x) 或fish 的范围内。
但是,因为Dog._type的type是"dog",Fish._type的type是"fish",所以Dog._type的值可以only 为"dog",Fish._type 的值only 为"fish"。我不明白为什么
myPetMap[newPet._type].push(newPet);
是错误的。
当传入的Pet是Dog时,newPet._type只能是"dog",新的宠物会被添加到myPetMap["dog"],这是一个Dog对象的数组。
当传入的Pet是Fish时,newPet._type只能是"fish",新的宠物会被添加到myPetMap["fish"],这是一个Fish对象的数组。
因为Pet 可能是这两种类型的_type 属性的类型是一个固定值,所以我看不出在Dog 被添加到@ 时会出现任何类型不匹配问题987654354@ 数组,反之亦然。 newPet._type 的值不需要为了将其添加到正确的数组中而变得具体或已知。
有没有办法解决这个问题?任何 Typescript 编译器选项或不同的编写方式?
编辑:
newPet._type的类型是string。
这是我的想法,但尝试更改 newPet._type 的值会产生其自身的错误...
newPet._type = "Something Else";
[ts] Type '"Something Else"' is not assignable to type '"dog" | "fish"'. [2322]
(property) _type: "dog" | "fish"
【问题讨论】:
-
newPet._type的类型是string。 -
@Pointy 感谢您的快速回复。我已编辑我的帖子以解决您的评论。
-
但显然如果你的
switch语句有效,_type的类型是字符串;switch语句与===逻辑进行比较。 -
@Pointy at runtime
_type是一个字符串,但 typescript 有字符串其他类型来模拟字符串常量。
标签: javascript typescript types