显示错误的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()

任何解释&有更好的解决方案吗?谢谢🙂️

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

您可以通过将过滤器函数声明为类型保护来帮助它。游戏场

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()

filter目前无法应用类型保护,这是一个悬而未决的问题。

您可以使用全能的Array.flatMap来进行过滤,而不是使用filter。。。您可以使用flatMap实现大多数数组转换。然而,如果您不熟悉flatMap操作,它的阅读效果就不会令人惊讶。

使用flatMap将其转换为filter的诀窍是为您不想要的项目返回一个空数组,为您想要的项目则返回一个1项目数组:

所以:

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()

游乐场连接

最新更新