我正在尝试有条件地将对象添加到类型值数组,但收到错误 尝试使用扩展运算符或导出到函数:(
假设
interface Foo {
type:'foo',
cool: string,
}
interface Bar {
type: 'bar'
lame: string,
}
interface FooBar = | Foo | Bar
const arr: FooBar[] = [
{
type: 'foo',
cool: 'this works great!',
},
...(true && <---- Will through error Types of property 'type' are incompatible 'string' is not assignable to '"bar" | "foo"'
[
{
type: 'bar',
lame: 'WHY THIS ERROR ON TYPE",
}
]
),
]
有什么想法吗?
除非有理由不这样做,否则 TypeScript 假定字符串文字的类型为
string
。在您的问题中,第一个对象 isn't 会以这种方式处理,因为它立即存储在一个数组中,其中字符串文字类型 "foo"
有效,但 string
无效。
那么为什么你的第二个对象没有得到同样的处理呢?因为它不会立即在 TypeScript 可以应用它的上下文中使用。它是表达式 (
true && {/*...*/}
) 的一部分,因此 type
属性仅键入为 string
,并且不能分配给文字类型 "foo"
或 "bar"
。
您可以通过将
as const
添加到您正在传播的数组中来修复它,因为这告诉 TypeScript 该属性不会被重新分配,因此它可以保持其最窄的类型(在本例中为 "bar"
):
interface Foo {
type:'foo',
cool: string,
}
interface Bar {
type: 'bar'
lame: string,
}
type FooBar = | Foo | Bar
const arr: FooBar[] = [
{
type: 'foo',
cool: 'this works great!',
},
...(true &&
[
{
type: 'bar',
lame: 'WHY THIS ERROR ON TYPE',
}
] as const // <====
),
]
(注意,我还必须修复几个语法错误。您不能使用
interface FooBar =
,所以我使用 type
代替,并且 lame
属性上的结束引号并不相同就像它的开场白一样。)