我使用以下联合类型:
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
}
)
发生了什么事?
答案 0 :(得分:1)
发生这种情况是因为当您使用字符串来初始化对象文字的字段时,字段的类型将被推断为string
而不是字符串文字类型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
})