在下面的代码中,我不想添加undefined
作为filteredDevice的类型注释。我认为,由于我过滤掉了未定义的设备,所以永远不要定义一个filteredDevice。
但是,如果我删除了undefined
类型注释,TypeScript就会抱怨Type 'ICouchDBDocument | undefined' is not assignable to type 'ICouchDBDocument'.
devices
.filter((device: ICouchDBDocument | undefined) => Boolean(device)) //should filter away all undefined devices?
.map((filteredDevice: ICouchDBDocument | undefined) => { ... })
如何更改代码,以便过滤器对类型注释产生影响?
答案 0 :(得分:2)
解决方案是传递一个类型保护功能,该功能告诉TypeScript您正在过滤掉类型的undefined
部分:
devices
.filter((device): device is ICouchDBDocument => Boolean(device)) //filters away all undefined devices!
.map((filteredDevice) => {
// yay, `filteredDevice` is not undefined here :)
})
如果您需要大量执行此操作,则可以创建一个适用于大多数类型的通用实用程序函数:
const removeNulls = <S>(value: S | undefined): value is S => value != null;
以下是一些示例:
devices
.filter(removeNulls)
.map((filteredDevice) => {
// filteredDevice is truthy here
});
// Works with arbitrary types:
let maybeNumbers: (number | undefined)[] = [];
maybeNumbers
.filter(removeNulls)
.map((num) => {
return num * 2;
});
(如果人们想将其与Boolean
类型一起使用,我没有在removeNulls
中使用number
函数-否则我们会意外滤除虚假的0
值!)
谢谢,我一直想知道同一件事,但是您的问题促使我终于解决了:)
看看TypeScript的lib.es5.d.ts
,Array.filter
函数具有此类型签名(它实际上在文件中有两个,但这与您的问题有关):
/**
* Returns the elements of an array that meet the condition specified in a callback function.
* @param callbackfn A function that accepts up to three arguments. The filter method calls the callbackfn function one time for each element in the array.
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
*/
filter<S extends T>(callbackfn: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[];
因此,此操作的关键是callbackfn的value is S
返回类型,表明它是user-defined type guard。