【问题标题】:Typescript: Filter array of conditional types AND have proper return type打字稿:过滤条件类型数组并具有正确的返回类型
【发布时间】:2020-03-11 22:21:51
【问题描述】:

我想过滤条件类型的数组并具有正确的返回类型。比如下面的代码:

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[]

也许用户定义的类型保护有一些棘手的用法?

【问题讨论】:

    标签: arrays typescript


    【解决方案1】:

    首先,foobar 的类型应该保留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
    

    Playground Link

    不确定它是否比断言好很多,但不幸的是,这已经尽可能接近了。

    【讨论】:

      猜你喜欢
      • 2021-09-18
      • 2022-07-07
      • 2021-09-17
      • 2019-11-25
      • 1970-01-01
      • 2021-02-10
      • 1970-01-01
      • 2020-05-27
      相关资源
      最近更新 更多