我试图通过使用Array.prototype.filter从数组中过滤null(未定义)元素,但TypeScript编译器似乎无法识别“filter”函数的派生数组,无法通过类型检查。
假设下面的简化代码中有一个数组(number| undefined)[]类型,并希望筛选undefined以适合数字[]数组。
const arry = [1, 2, 3, 4, "5", 6];
const numArry: number[] = arry
.map((i) => {
return typeof i === "number" ? i : void 0;
})
.filter((i) => i);
错误说:
类型'(编号|undefined)[]'不能分配给类型'number[]'。类型'编号|undefined'不能赋值给类型' number '。类型“undefined”不能赋值给类型“number”。
我可以将结果数组转换为number[],就像下面这样知道filter函数会删除undefined。
const arry = [1, 2, 3, 4, "5", 6];
const numArry: number[] = (arry
.map((i) => {
return typeof i === "number" ? i : void 0;
})
.filter((i) => i) as Number[]);
有没有比铸造更好的方法来实现这一点?
环境:启用strictNullChecks的TSC2.1。
6条答案
按热度按时间7eumitmz1#
使用TypeScript的用户定义类型保护功能:
看看回调函数中的
i is number
。这个技巧使我们能够转换Array.filter结果的类型。vnjpjtjt2#
解决方案
创建 type guard:
使用它作为类型 predicate :
说明
Array.prototype.filter
有一些过载。其中一个知道返回值将取决于 predicate 函数。它使用了一个类型保护:使用适当的类型保护(而不是采用快捷方式和依赖隐式强制)帮助TypeScript选择这个特定的重载。
a7qyws3x3#
以Typescript理解的类型安全方式从数组中筛选值的最简单方法是使用
flatMap
而不是map
,并为您想要删除的任何内容返回一个空数组。示例:
flatMap
分两步工作。首先,它Map数组并执行你给它的任何函数。然后将其中的所有数组展平。1.Map数组并得到:
[ 1, 2, 3, 4, [], 6, 7, [], 9, 0 ]
1.展平数组中的任意数组:
[ 1, 2, 3, 4, 6, 7, 9, 0 ]
瞧!现在你有了一个类型化的数组,Typescript很高兴。
qvtsj1bj4#
可以定义自己的完全类型安全的过滤器函数,它接受数组和用户定义的类型保护函数,并返回不同类型的数组。
不知道有多有用,但它是:
它可以这样使用:
不幸的是,
isNumber()
必须定义为单独的显式类型函数,因为编译器不够聪明,无法识别内联函数e => typeof e === 'number'
也是一个类型保护。xcitsw885#
map(...)
函数签名为:在您的情况下,泛型类型
U
将是:number | undefined
filter(...)
签名为:由于
T
来自数组接口签名(Array<T>
),因此返回类型将是与value
参数类型相同的数组(泛型类型T
)。在你的情况下,number | undefined
。这就是为什么返回类型是
number | undefined
。在此基础上,您将需要使用强制转换表达式。如果你不希望出现这种情况,你可以删除
--strictNullChecks
标志。rlcwz9us6#
解决方案
我反对使用类型保护,因为你可以编写任何逻辑,它仍然可以工作。