Typescript 当从函数返回联合类型时,为什么类型推断会丢失?

Typescript 当从函数返回联合类型时,为什么类型推断会丢失?,typescript,union-types,Typescript,Union Types,我正在使用以下联合类型: interface A { type: 'A'; } interface B { type: 'B'; bProp: number } type X = A | B 当我试图在数组中使用它并映射到它时,我得到一个编译错误: let list: X[] = [] let list2: X[] = list.map(el => { return true ? { type: 'B', bProp: 1 } : el } )

我正在使用以下联合类型:

interface A {
    type: 'A';
}

interface B {
    type: 'B';
    bProp: number
}

type X = A | B
当我试图在数组中使用它并映射到它时,我得到一个编译错误:

let list: X[] = []
let list2: X[] = list.map(el => {
    return true ? { type: 'B', bProp: 1 } : el
    }
)

(39,5): Type '(A | { type: string; bProp: number; })[]' is not assignable to type 'X[]'.
  Type 'A | { type: string; bProp: number; }' is not assignable to type 'X'.
    Type '{ type: string; bProp: number; }' is not assignable to type 'X'.
      Type '{ type: string; bProp: number; }' is not assignable to type 'B'.
        Types of property 'type' are incompatible.
          Type 'string' is not assignable to type '"B"'.
但是,当我将类型的记录提取到局部变量并显式地键入它时,它可以工作:

let list: X[] = []
let list2: X[] = list.map(el => {
        let tmp: B = { type: 'B', bProp: 1 };
        return true ? tmp : el
    }
)

发生了什么?

发生这种情况是因为当您使用字符串contant初始化object literal字段时,字段的类型将被推断为
string
而不是字符串literal类型
B
,因此
{type:'B',bProp:1}
被键入
{type:string,bProp:number}
B
不兼容

您可以显式地将字符串转换为字符串文字类型:

let list: X[] = []
let list2: X[] = list.map(el => {
    return true ? { type: 'B' as 'B', bProp: 1 } : el
})
第二个示例之所以有效,是因为您显式地将
tmp
键入
B
,因此编译器只需检查对象文本是否与声明的
B
类型兼容,而不必确定
tmp
的类型。这就是为什么这也会起作用的原因:

let list2: X[] = list.map(el => {
    return true ? { type: 'B', bProp: 1 } as B : el
})