在TypeScript数组中如何优雅的过滤掉null
编码过程中,经常需要过滤掉可选数组中的某个类型的值,如过滤null
。一般使用数组的filter
即可完成,如下:
const arr: (string | null)[] = []
const fArr = arr.filter((item) => item !== null)
// fArr type is: (string | null)[]
如上使用filter
,确实实现了过滤掉null
的需求,但是TypeScript
对结果的类型还是推断为(string | null)[]
,并不是我们期望的string[]
。 如果希望TypeScript
正确识别出过滤掉null
后的类型,我们应该如何做呢?可以使用如下方法:
- 使用
as
指定过滤后的结果的类型 - 使用
is
指定返回项的类型 - 使用
is+Exclude
来收窄类型。
使用as
指定结果类型
通过as
手动指定过滤结果的类型,如下:
const arr: (string | null)[] = []
const fArr = arr.filter((item) => item !== null) as string[]
// fArr type is: string[]
这是最简单的实现,通过指定结果的类型来实现。 这个方案需要注意的是,我们要能拿到类型,如果使用三方库,我们可能获取不到类型申明,就比较麻烦。还有就是不要把类型写错了,影响到后面的推断。
使用is
指定返回项的类型
同使用使用as
指定结果类型,差不多。这里我们只需要指定每次处理后的返回的结果的类型,这样TypeScript
就能推断出过滤后的结果类型。
const arr: (string | null)[] = []
const fArr = arr.filter((item): item is string => item !== null)
// fArr type is: string[]
这个方案也是可行的,但是还是存在同样的问题,当我们无法获取到类型时,是无法使用该方案的。这就衍生出了下面的一种处理方式。
使用is+Exclude
来收窄类型
如下,可以使用is+Exclude
的方式来收窄类型。
const arr: (string | null)[] = []
const sArr = arr.filter((item): item is Exclude<typeof item, null> => item !== null)
// fArr type is: string[]
这里使用了Exclude
来排除掉null
类型,然后再使用is
来指定返回值的类型,这样TypeScript
就能正确推断出过滤后的结果类型。 这个方案就没有获取具体类型得要求,我们通过typeof
来处理的,不需要知道具体类型。
提示 这里还有个小技巧,如果想顺便处理掉空字符,可以改一下判断条件
const arr: (string | null)[] = []
const sArr = arr.filter((item): item is Exclude<typeof item, null> => !!item)
// fArr type is: string[]
总结
上面介绍了如何在TypeScript
数组中过滤掉null
,并正确推断出过滤后的结果类型。 如果比较简单,as
和is
都是不错的选择。 如果不能获取到具体的类型,我们可以使用is+Exclude
来收窄类型。
注意 虽然这里举例是过滤数组中的null
项。但是思路是通用的,也可以在过滤其他类型使用类似的方式。