forEach 循环中设置的变量类型错误
Variable set in forEach loop getting wrong type
在 forEach
回调函数中设置变量时,该变量的类型似乎不正确。一个简单的例子:
let foo: (string | null) = null;
[1,2,3].forEach((i) => {
foo = "bar";
});
if(foo == null) {
throw new Error("not found")
}
# Typescript complains that `length` is not a property of type `never`
console.log(foo.length)
在 forEach
之后,我希望 foo
的类型是 string | null
,但实际上它只是 null
。根据 console.log
行,我希望它只是 string
,但实际上是 never
(因为我们已经排除了 null
作为 [=20= 的可能性) ] 扔.
重要的是,上面的代码(减去 : (string | null)
位)在普通 JavaScript 中工作得很好 - 这纯粹是我和 TypeScript 编译器无法以某种方式正确通信的情况。
总之:
- 如果有人能解释为什么会这样,我会很高兴,这样我就能更好地理解 Typescript 并且
- 我该如何解决这个问题?我可以在 console.log 之前打一个
foo = foo as string
,但肯定有更好的方法吗?
这不是 TypeScript 的行为,而是 EcmaScript 的行为。 forEach
为变量定义了一个范围,所以里面发生了什么,它仍然在里面。
这是控制流分析的权衡之一。
通过注释类型 string | null
,您告诉编译器变量显然需要任何一种类型的值。然后,您对 null
进行赋值,这让编译器将类型缩小为 null
.
您希望 TypeScript 考虑回调内的赋值并放弃缩小,但它没有。这是团队在决定作为参数传递给高阶函数的函数中发生的突变是否应该泄漏到外部作用域时做出的权衡。
请参阅 this source repo 关于此事的讨论。
在 forEach
回调函数中设置变量时,该变量的类型似乎不正确。一个简单的例子:
let foo: (string | null) = null;
[1,2,3].forEach((i) => {
foo = "bar";
});
if(foo == null) {
throw new Error("not found")
}
# Typescript complains that `length` is not a property of type `never`
console.log(foo.length)
在 forEach
之后,我希望 foo
的类型是 string | null
,但实际上它只是 null
。根据 console.log
行,我希望它只是 string
,但实际上是 never
(因为我们已经排除了 null
作为 [=20= 的可能性) ] 扔.
重要的是,上面的代码(减去 : (string | null)
位)在普通 JavaScript 中工作得很好 - 这纯粹是我和 TypeScript 编译器无法以某种方式正确通信的情况。
总之:
- 如果有人能解释为什么会这样,我会很高兴,这样我就能更好地理解 Typescript 并且
- 我该如何解决这个问题?我可以在 console.log 之前打一个
foo = foo as string
,但肯定有更好的方法吗?
这不是 TypeScript 的行为,而是 EcmaScript 的行为。 forEach
为变量定义了一个范围,所以里面发生了什么,它仍然在里面。
这是控制流分析的权衡之一。
通过注释类型 string | null
,您告诉编译器变量显然需要任何一种类型的值。然后,您对 null
进行赋值,这让编译器将类型缩小为 null
.
您希望 TypeScript 考虑回调内的赋值并放弃缩小,但它没有。这是团队在决定作为参数传递给高阶函数的函数中发生的突变是否应该泄漏到外部作用域时做出的权衡。
请参阅 this source repo 关于此事的讨论。