在TypeScript中将变量定义为区分并集的一个变量
我有以下typescript代码,它使用一个有区别的并集来区分一些类似的对象:在TypeScript中将变量定义为区分并集的一个变量,typescript,discriminated-union,Typescript,Discriminated Union,我有以下typescript代码,它使用一个有区别的并集来区分一些类似的对象: interface Fish { type: 'FISH', } interface Bird { type: 'BIRD', flyingSpeed: number, } interface Ant { type: 'ANT', } type Beast = Fish | Bird | Ant function buildBeast(animal: 'FISH' | 'BIRD' |
interface Fish {
type: 'FISH',
}
interface Bird {
type: 'BIRD',
flyingSpeed: number,
}
interface Ant {
type: 'ANT',
}
type Beast = Fish | Bird | Ant
function buildBeast(animal: 'FISH' | 'BIRD' | 'ANT') {
const myBeast: Beast = animal === 'BIRD' ? {
type: animal,
flyingSpeed: 10
} : {type: animal}
}
在函数buildBeast
中,它接受符合myBeast
类型的所有可能的类型的字符串,但由于以下错误,它不允许我将myBeast
声明为typeBeast
:
Type '{ type: "BIRD"; flyingSpeed: number; } | { type: "FISH" | "ANT"; }' is not assignable to type 'Beast'.
Type '{ type: "FISH" | "ANT"; }' is not assignable to type 'Beast'.
Type '{ type: "FISH" | "ANT"; }' is not assignable to type 'Ant'.
Types of property 'type' are incompatible.
Type '"FISH" | "ANT"' is not assignable to type '"ANT"'.
Type '"FISH"' is not assignable to type '"ANT"'.
似乎所有情况下都会产生正确的Beast
,但TS似乎在强制不同类型时遇到了问题。有什么想法吗?通过遍历联合类型并确保每种类型都有效,TypeScript是不行的。如果它这样做了,或者如果你能告诉它这样做,那就太好了,事实上我已经做到了,但目前还不可能做到
目前,我所知道的唯一解决方法是我在建议中提到的变通方法:要么执行类型断言(这是不安全的),要么让编译器遍历不同的情况(这是多余的)。以下是两种不同的方式:
断言:
function buildBeast(animal: 'FISH' | 'BIRD' | 'ANT') {
const myBeast: Beast = animal === 'BIRD' ? {
type: animal,
flyingSpeed: 10
} : {type: animal} as Fish | Ant;
}
浏览不同的案例:
function buildBeast(animal: 'FISH' | 'BIRD' | 'ANT') {
const myBeast: Beast = animal === 'BIRD' ? {
type: animal,
flyingSpeed: 10
} : (animal === 'FISH') ? {
type: animal
} : { type: animal };
}
嘿,如果您认为TypeScript应该允许您将控制流分析分布到联合类型上,也许可以考虑这个建议并给出一个很好的答案,我实际上通过类型断言使它工作起来。感谢您花时间将您的建议添加到TypeScipt中,我会仔细阅读并确认