在下面的例子中:
type Foo = () => void;
let a: Foo | undefined = undefined;
const c = () => { a = () => console.log("Hi!") };
c();
if (a) {
a();
}
在第4行,a
的类型是let a: Foo | undefined
,而在第8行是let a: never
。因此,tsc
在第8行显示了这个错误:Type 'never' has no call signatures
。
但是如果第2行是let a: Foo | undefined;
(删除了变量赋值),则不会发生这种情况。
我想这将与类型推断有关。文档指出:
在TypeScript中,在没有显式类型注释的情况下,可以使用类型推断来提供类型信息。 设x= 3;^设x:数
但是这个例子有一个显式的类型注释。
据我所知,TS无法知道函数c
是否将被执行,因此,a
将被分配。这就是为什么我在声明中明确定义了a
的类型。
那么,为什么第8行不尊重为a
定义的类型呢?
发布于 2021-09-02 09:51:56
正如你在问题中所指出的,这是不合理的行为。这一行为在GitHub问题跟踪器上的一个公开发行的题为控制流分析中的权衡的问题中得到了注意。
乐观:当地人的坏行为 TypeScript编译器有如下代码: enum令牌{ Alpha,Beta,Gamma } let Token = Token.Alpha;函数nextToken() { Token.Beta;}函数maybeNextToken() { if (.){ nextToken();}函数doSomething() { if (令牌!== Token.Alpha) { maybeNextToken();} //这可能吗?如果(令牌=== Token.Alpha) { //某事发生} 乐观地假设
token
没有被maybeNextToken
错误地修改,将token === Token.Alpha
标记为不可能。然而,在其他情况下,这是一个很好的检查做!见后面的例子。
问题是,在其他情况下,使编译器更加悲观将是有害的,因为编译器将无法检测到代码中的实际错误。在写这个答案的时候,这个问题已经有5年多了,而且还没有解决,看起来语言设计师们还没有就是否需要做些什么达成一致,如果是这样的话。
https://stackoverflow.com/questions/69034741
复制相似问题