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,则无法再次保留缩小的类型