【问题标题】:Typescript iterate and filter an array of different types打字稿迭代和过滤不同类型的数组
【发布时间】:2022-11-22 18:32:20
【问题描述】:

有谁知道我如何在由两种不同类型组成的数组中过滤并获取大于 250 的数字,即

interface Foo {
    myNumber: number
}

interface Bar {
    present: boolean
}

const myArray : (Foo | Bar)[] = [{myNumber: 200}, {myNumber:600}, {myNumber:450}, {present: true}]

myArray.filter((it: Foo|Bar) => it?.myNumber >= 250)

我得到的错误是“属性‘myNumber’在‘Foo | Bar’类型上不存在。”

我知道错误消息背后的原因,但是想不出一个直接的解决方案 atm。

playground

【问题讨论】:

  • 这回答了你的问题了吗? Typescript property does not exist on union type
  • 你为什么使用Foo & Bar?您可以在一个界面中同时使用两者吗?
  • @托比亚斯。是的,试过 myArray.filter((it: Foo|Bar) => "myNumber" in it? it.myNumber >= 250 : false),它确实解决了问题。如果有任何使用过滤器,我正在寻找更优雅的解决方案。
  • @Mbistami 是的,我们可以。但是,我不会 -> 遗留代码
  • @AluanHaddad 或我可以删除所有类型,使用未知或任何类型。或者更好的办法是摆脱整个打字稿并使用 javascript :D

标签: javascript typescript


【解决方案1】:

我不明白你为什么使用两个不同的界面,但是,
在我看来,可以使用 optional fields 在一个 interface 中完成。
这就是一个界面的样子

interface Foo {
    myNumber?: number,
    present?: boolean
}

const myArray : (Foo)[] = [{myNumber: 200}, {myNumber:600}, {myNumber:450}, {present: true}]

console.log(myArray.filter((it: Foo) => it?.myNumber && it?.myNumber >= 250))

如果你让我知道真的需要两个接口我可以更新答案...

【讨论】:

    【解决方案2】:

    让 TS 像 Aluan Haddad 在 cmets 中建议的那样推断数组的类型当然是一种方法。但是,我假设您希望将数组键入为 Foo | Bar 以确保该数组不包含任何其他内容。

    但是,您可以将 TS 自行推断的类型定义为

    type FooOrBar = (Foo & {
        [Key in keyof Bar]?: never;
    }) | (Bar & {
        [Key in keyof Foo]?: never;
    });
    

    并将此类型用于 it

    myArray.filter((it: FooOrBar) => it.myNumber !== undefined && it?.myNumber > 250);
    

    或者也许避免使用 undefined-检查

    myArray.filter((it: FooOrBar) => Number(it?.myNumber) > 250);
    

    Playground

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-13
      • 2019-10-13
      • 2022-09-24
      • 1970-01-01
      • 2019-07-26
      • 1970-01-01
      • 2016-08-03
      • 2019-04-11
      相关资源
      最近更新 更多