Typescript 在后续的Array.prototype.map中丢失类型缩小
任何人都可以帮助解释以下类型检查错误:Typescript 在后续的Array.prototype.map中丢失类型缩小,typescript,Typescript,任何人都可以帮助解释以下类型检查错误: interface Foo { kind: 'foo'; a: string; } interface Bar { kind: 'bar'; b: number; } type FooBar = Foo | Bar; interface Container { ids: number[]; fooBar: FooBar; } const cont: Container = { ids: [1,
interface Foo {
kind: 'foo';
a: string;
}
interface Bar {
kind: 'bar';
b: number;
}
type FooBar = Foo | Bar;
interface Container {
ids: number[];
fooBar: FooBar;
}
const cont: Container = {
ids: [1, 2],
fooBar: { kind: 'foo', a: 'a' },
};
switch (cont.fooBar.kind) {
case 'foo':
console.log(cont.fooBar.a); // OK
cont.ids.map((id) => {
console.log(`${id} - ${cont.fooBar.a}`);
// Property 'a' does not exist on type FooBar
// Property 'a' does not exist on type Bar
})
break;
case 'bar':
console.log(cont.fooBar.b); // OK
cont.ids.map((id) => {
console.log(`${id} - ${cont.fooBar.b}`);
// Property 'b' does not exist on type FooBar
// Property 'b' does not exist on type Foo
})
break;
}
.您可以通过将
fooBar
抓取到本地const
,并在开关中使用fooBar
而不是cont.fooBar
来修复它:
const { fooBar } = cont; // <====
switch (fooBar.kind) {
case 'foo':
console.log(fooBar.a); // OK
cont.ids.map((id) => {
console.log(`${id} - ${fooBar.a}`); // OK now
})
break;
case 'bar':
console.log(fooBar.b); // OK
cont.ids.map((id) => {
console.log(`${id} - ${fooBar.b}`); // OK now
})
break;
}
const{fooBar}=cont;//{
console.log(`${id}-${fooBar.a}`);//现在确定
})
打破
“酒吧”一案:
console.log(fooBar.b);//好啊
cont.id.map((id)=>{
console.log(`${id}-${fooBar.b}`);//现在确定
})
打破
}
最初,我在每个案例中都是这样做的,但TypeScript也很满意上面的情况
我认为这是因为TypeScript不能确定回调是同步的,而且如果回调是异步的,以后可能会被其他代码更改cont.fooBar
,所以不能确定缩小的类型仍然正确。在当地抓住它可以消除这种疑虑。这一理论得到以下事实的支持:如果你让它let{fooBar}=cont代码>而不是const{fooBar}=cont代码>,则无法再次保留缩小的类型