typescript - 打字稿:空值检查在 array.map 函数中不起作用
问题描述
为什么我之前在 map 函数之前检查的可为 null 类型在 map 中不起作用?
function x() {
let y: number | null;
y = null;
if (!y) {
return [];
}
return [1, 2, 3, 4].map((z) => {
// error: y cannot be null
return z + y;
})
}
解决方案
由于您使用的是类型保护let
而不是const
类型保护,因此不能保证您不会修改该值,也就是说 TS 采用了关于类型 ( number | null
) 的原始假设,您需要再次检查它。改变y
成const
帮助。
重新分配 y 的示例
考虑到您可能在检查后,再次设置y
为null
.
function x(defValue: number | null) {
let y = defValue;
if (!y) {
return [];
}
// and below the change even though we checked that before the check is not safe
y = null;
return [1, 2, 3, 4].map((z) => {
// no error
return z + y;
})
}
我如何更改值的另一个示例是 - 在地图本身中,请考虑:
return [1, 2, 3, 4].map(z => {
y = null // changed to null!!
return z;
}).map((z) => {
// error as it can be null
return z + y;
})
它不安全检查的主要原因是我们不能说回调何时会被调用,我们在这个范围内声明它的事实并不意味着它会同时执行,例如,如果它会Promise.then
,执行时间是未知的。考虑这样的代码:
function x(defValue: number | null) {
let y = defValue;
if (!y) {
return [];
}
httpClient.get('http://something').then((z: number) => {
// error correctly because y is null
return z + y;
});
y = null; // this code is executed before then
}
另一个例子是暴露y
外部可能发生的变化。考虑:
function x(defValue: number | null) {
let y = defValue;
if (!y) {
return null
}
return {
f: (z: number) => z + y, // error as y can be null because yToNull can change it
yToNull: () => { y = null } // modify the y to null
}
}
const fg = x(1);
if (fg) {
fg.yToNull();
fg.f(2); // y is null inside the scope of f
}
使用 const 进行持久保护
如您所见,let
在整个闭包中将变量视为由守卫缩小是非常不安全的。
使用const
这种重新分配是不可能的,并且 TS 能够推断出闭包范围内的值的窄类型。
function x(defValue: number | null) {
const y = defValue;
if (!y) {
return [];
}
// any change of y type is not possible with const
return [1, 2, 3, 4].map((z) => {
// no error as y cannot be re-assigned
return z + y;
})
}
推荐阅读
- profiling - 如何分析 LINQPad 查询?
- java - 如何在圆形语音气泡内制作带有照片的谷歌地图标记?
- r - 从函数返回 ggplot 对象
- r - 使用 fwrite r 打印时禁用指数表示法
- r - 嵌套 gapply()、dapply 或 spark_apply() 函数?
- animation - Javafx 碰撞检测 inTimeLine
- python - 如何访问存储在Python变量中的目录列表
- python - 基于 Mac 的小型 post house 希望运行 Windows 机器,但我们依赖于一些 Python 脚本
- python - 如何参数化测试函数:Pytest?
- qt - 使我在 QListview 中列出的项目在单击时发出信号