typescript - 从未定义的值中过滤数组
问题描述
有人可以向我解释为什么在这种情况下:
const dataValues: ValueRange[] = res.data.valueRanges.filter((range: ValueRange) => range.values);
const formattedValues: Array<SheetData | undefined> = dataValues.map(this.formatSheetRanges);
const sheetData: Array<SheetData> = formattedValues.filter((sheetData: SheetData | undefined) => sheetDataGuard(sheetData));
function sheetDataGuard(data: SheetData | undefined): data is SheetData {
return !!(<SheetData>data).user;
}
sheetData 数组仍然会抱怨它的类型是
Array<SheetData | undefined>
但是如果我将最后一个过滤更改为:
const sheetData: Array<SheetData> = formattedValues.filter(sheetDataGuard);
打字稿不再抱怨了吗?
解决方案
这是因为Array<T>.filter()
标准 TypeScript 库中方法的类型具有重载签名,如果已知回调函数是用户定义的类型保护函数,则该签名专门缩小返回的数组元素类型:
interface Array<T> {
filter<S extends T>(
callbackfn: (value: T, index: number, array: T[]) => value is S,
thisArg?: any
): S[];
}
由于 of 的类型sheetDataGuard
可分配给(value: SheetData | undefined, index: number, array: Array<SheetData | undefined>) => value is SheetData
,因此调用withfilter
作为参数将导致编译器选择带有inferred for 的重载。Array<SheetData | undefined>
sheetDataGuard
callbackfn
SheetData
S
但是当你调用它时(sheetData: SheetData | undefined) => sheetDataGuard(sheetData)
,该函数的类型被推断为 return just boolean
。那是因为用户定义的类型保护函数不会传播,也不会为您推断。一旦你开始使用它,编译器就会将类似的类型x is Y
扩展到它。boolean
您可以通过使用箭头函数返回类型注释告诉编译器您的箭头函数回调也是类型保护,如下所示:
const sheetData: Array<SheetData> = formattedValues.filter(
(sheetData: SheetData | undefined): sheetData is SheetData =>
sheetDataGuard(sheetData)
);
编译器应该很高兴。当然,如果你要这样做,你不妨忘记定义sheetDataGuard
为一个单独的函数:
const sheetData: Array<SheetData> = formattedValues.filter(
(sheetData: SheetData | undefined): sheetData is SheetData =>
!!sheetData
);
无论如何,希望这会有所帮助。祝你好运!
推荐阅读
- python - 如何在 Django 3.0.3 的默认 admin_User 表中添加附加字段
- python - 如何使用 BeautifulSoup 在 div 中抓取代码?
- akka - 如何自行重启 Akka 演员?
- sql - 使用 DISTINCT 内连接 SQL
- django - 在 django 和 postgres 中实现类似的系统
- python-3.x - 使用 cython/numba 进行 Pandas groupby 聚合
- javascript - 如何使用angular8切换行
- java - ActiveMQ InactivityMonitor 参数未应用于 HTTP 传输连接
- ios - 如何解决此冲突的一致性错误?
- javascript - vscode javascript 保留关键字语法颜色