显示错误的打字稿过滤器无法分配给类型

时间:2020-10-22 10:15:58

标签: typescript

这不起作用。显示错误 Type '(Person | null)[]' is not assignable to type 'Person[]'. Type 'Person | null' is not assignable to type 'Person'. Type 'null' is not assignable to type 'Person'.

interface Person {
  name: string;
}

function filterPersons(persons: Array<Person | null>): Array<Person> {
    return persons.filter(person => person !== null)
}

function run() {
    const persons: Array<Person | null> = []
    persons.push(null)
    filterPersons(persons)
}

run()

但这是可行的

interface Person {
  name: string;
}

function filterPersons(persons: Array<Person | null>): Array<Person> {
    return persons.filter(person => person !== null) as Array<Person>
}

function run() {
    const persons: Array<Person | null> = []
    persons.push(null)
    filterPersons(persons)
}

run()

任何解释,还有更好的解决方案吗?谢谢?️

3 个答案:

答案 0 :(得分:3)

第一段代码persons.filter(person => person !== null)不会进行类型检查,因为TSC无法理解您的代码实际上是将数组项类型缩小为Person

您可以通过将过滤器函数声明为类型防护来提供帮助。 Playground

interface Person {
  name: string;
}

// notice person is Person return type
const isPerson = (person: Person | null) : person is Person => person !== null

function filterPersons(persons: Array<Person | null>): Array<Person> {
    return persons.filter(isPerson)
}

function run() {
    const maybePersons: Array<Person | null> = []
    maybePersons.push(null)
    const persons: Person[] = filterPersons(maybePersons)
    console.log(persons)
}

run()

答案 1 :(得分:2)

filter当前无法应用类型保护,有an open issue for this

答案 2 :(得分:1)

您可以使用功能强大的Array.flatMap代替filter进行过滤...您可以根据flatMap来实现大多数数组转换。但是,如果您不熟悉flatMap操作,它的阅读效果就不会很好。

使用flatMap将其转换为filter的技巧是,为不需要的项返回一个空数组,为您想要的项返回一个1-item数组:

如此:

interface Person {
  name: string;
}

function filterPersons(persons: Array<Person | null>): Array<Person> {
    return persons.flatMap(p => p === null ? [] : [p]) // Array<Person> yay!
}

function run() {
    const persons: Array<Person | null> = []
    persons.push(null)
    filterPersons(persons)
}

run()

playground link