typescript - TypeScript 未选择过滤器以删除未定义的项目
问题描述
在下面的代码中,我不想添加undefined
为过滤设备的类型注释。我认为过滤设备永远不应该是未定义的,因为我过滤掉了未定义的设备。
但是如果我删除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) => { ... })
如何更改我的代码以使过滤器对类型注释产生影响?
解决方案
解决方案是传递一个类型保护函数,告诉 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[];
所以,这其中的关键是value is S
callbackfn 的返回类型,说明它是一个用户自定义的类型守卫。
推荐阅读
- javascript - Is there a way to get images from backend to frontend once they're separate modules?
- c# - Clear my view page when I hit finish button
- google-cloud-datastore - How to update single property of multiple entities in specific kind of datastore?
- ios - Is there any way to automatically Delete/Remove Push notification after 2 hours in iOS?
- python - 无论如何,是否有将对象限制为 Python 中的特定数据类型?
- php - Instanceof with string name of class instead instantiating class
- javascript - 如何使用 node.js 更新 MongoDB 中的用户数据
- django - If Else 在 Djnago 视图中
- katalon-studio - Unable to set the recorded values in the field while playing the recording
- python - How to have a mix of both Celery Executor and Kubernetes Executor in Apache Airflow?