我想过滤条件类型的数组,并具有正确的返回类型。例如,使用以下代码:
const foo = {
type: "foo" as const,
foo: 123
}
const bar = {
type: "bar" as const,
bar: 123
}
const arr = [foo, bar]
const filteredArr = arr.filter(val => val.type === 'foo');
filteredArr.map(val => {
val.foo //Typescript blows up! Property foo does not exist on type
})
我想出的唯一解决方案是强制转换过滤后的数组:
type Foo = typeof foo;
const filteredArr = arr.filter(val => val.type === 'foo') as Foo[];
但是似乎应该有一种打字稿应该足够聪明,可以推断出数组仅被过滤为Foo[]
。
也许是用户定义类型防护的一些棘手用法?
答案 0 :(得分:3)
首先,foo
和bar
的类型应保留type
的文字类型,以便具有可区分的联合(假设您可能无论如何都具有类型别名或接口) 。
filter
将采用自定义类型防护,但不幸的是无法从使用中推断出类型防护,因此函数val => val.type === 'foo'
不会缩小类型的范围。
我们可以做的是显式注释函数,以使编译器知道我们正在缩小函数的类型:
const foo = {
type: "foo" as const, // added to preserve ,
foo: 123
}
const bar = {
type: "bar" as const, // added to preserve
bar: 123
}
const arr = [foo, bar]
const filteredArr = arr.filter((val): val is typeof foo => val.type === 'foo')
filteredArr.map(x => x.foo) // ok
不确定它比断言要好得多,但是很不幸,这与声明很接近。