我遇到了一个有趣的案例,TypeScript编译器(带有strictNullChecks === true
)不允许我将带有空值的数组传递给到需要数字数组的函数。
以下是显示问题的代码示例:
class Test {
constructor() {
const values = [1, 2, null, 4].filter(x => x);
this.printNumberArray(values);
}
printNumberArray(values: number[]) {
console.log(values);
}
}
这会导致红色波浪线出现在values
下,并显示以下错误:
Argument of type '(number | null)[]' is not assignable to parameter of type 'number[]'.
Type 'number | null' is not assignable to type 'number'.
Type 'null' is not assignable to type 'number'.
const values: (number | null)[]
filter
保证消除空值,但显然编译器无法识别它。
我可以通过将数组中的所有值转换为数字来解决这个问题,如下所示:
const values = [1, 2, null, 4]
.filter(x => x)
.map(x => x as number);
但我无法摆脱“必须有更好的方式”的感觉。
所以这是我的问题,有没有推荐/最佳实践方法来做到这一点?
答案 0 :(得分:3)
你可以使用这样一个事实:filter
有一个类似于此的过载,它适用于类型保护:
filter<S extends T>(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[];
所以您需要做的就是将代码更改为:
class Test {
constructor() {
const isNotNull = <T>(x: T): x is NonNullable<T> => !!x;
const values = [1, 2, null, 4].filter(isNotNull);
this.printNumberArray(values);
}
printNumberArray(values: number[]) {
console.log(values);
}
}