我一直在使用带有标记的联合类型来进行打字稿辨别,并且遇到了一些奇怪的事情。如果我打开实际的对象属性,那么一切都会按预期进行。但是,如果我使用解构,打字稿会报告错误。我认为这与解构在编译时的实际工作方式有关,但我不确定。您可以在playground
上看到此示例代码interface Foo {
discriminate: 'FOO';
details: string;
}
interface Bar {
discriminate: 'BAR';
numbers: number;
}
type FooOrBar = Foo|Bar;
const foo : Foo = {
discriminate: 'FOO',
details: 'Blah Blah Blah'
}
const breakTaggedUnionWithRest = ({discriminate, ...fooBar} : FooOrBar) => {
switch(discriminate) {
case 'FOO':
console.log(fooBar.details);
break;
}
}
interface Foo2 {
discriminate: 'FOO2';
details: string;
}
interface Bar2 {
discriminate: 'BAR2';
details: number;
}
type FooOrBar2 = Foo2|Bar2;
const breakTaggedUnionWithoutRest = ({discriminate, details} : FooOrBar2) => {
switch(discriminate) {
case 'FOO2' : return details.toLowerCase();
}
}
const workingExample = (fooOrBar: FooOrBar) => {
switch(fooOrBar.discriminate) {
case 'FOO': return fooOrBar.details;
}
}
const workingExample2 = (fooOrBar: FooOrBar2) => {
switch(fooOrBar.discriminate) {
case 'FOO2': return fooOrBar.details.toString;
}
}
答案 0 :(得分:1)
如果不进行分解,则discriminator属性上的switch
-case
可使TypeScript缩小整个fooOrBar
对象的类型并正确推断该对象上其他属性的类型宾语。这是因为TypeScript理解您正在尝试通过对象的属性来进行区分。
但是,通过解构,discriminate
和其他变量(在第一个示例中为fooBar
,在第二个示例中为details
)彼此无关。结果,在case
的TypeScript中没有推断出另一个变量的类型可能会变窄,因为switch
下的变量和您尝试访问的变量在任何情况下都不相关。在这一点上。