【问题标题】:Compilation error when using a variable initialized by an enum value inside a switch使用由开关内的枚举值初始化的变量时出现编译错误
【发布时间】:2020-11-17 21:48:15
【问题描述】:

Playground Link

我在使用 Playground 链接中提供的代码时遇到编译错误,我不明白为什么。

我正在创建一个具有枚举值的变量:

intellisense 告诉我,我的变量的类型是按预期推断的:ValidatorMessageState。就像将 true/false 分配给变量时一样,typescript 推断一个布尔值而不是 true 或 false 作为类型。

然后我切换它: 现在智能感知告诉我变量的类型已经改变,即使我在创建它和打开它之间什么也没做。 变量现在具有枚举值的类型,而不是枚举。

我发现另一件事很奇怪:如果我引入一些闭包,打字稿不会给我错误(我已经在操场上评论了这部分)

我想我在这里做错了什么,但我不明白是什么。谁能给我解释一下?

更新游乐场:Playground Link

【问题讨论】:

    标签: typescript enums


    【解决方案1】:

    这是一项功能,而不是错误 :)

    这是打字稿在做control flow analysis。控制流分析仅在某些代码结构中开始发挥作用,例如 switch 语句。

    一旦到达 switch 语句,typescript 编译器就会尝试缩小 maxStateEncoutered 的类型。在您的情况下,它只能是ValidatorMessageState.Error,因为这是唯一的分配。并且打字稿对此并没有错...如果您以某种动态方式分配变量(例如:返回ValidatorMessageState的函数),错误就会消失。

    至于forEach 中的代码,打字稿无法推断闭包/回调中的代码。原因的要点是它不知道这段代码何时运行。当然,在forEach 中它会立即运行,但打字稿不知道该功能。在像addEventListener 这样的函数中,您传递的函数可以随时运行,而maxStateEncoutered 在此之前可能会发生变化,因此它不能再推断maxStateEncoutered 是特定类型ValidatorMessageState.Error。如果您将maxStateEncouteredlet 更改为const,您也会在forEach 中看到此错误。

    【讨论】:

    • 好的,谢谢你的回答。这和我猜想的差不多。但是像 let maxStateEncoutered: ValidatorMessageState = ValidatorMessageState.Error; 这样的东西会很好。有效,因为我给出了类型。
    • let maxStateEncoutered = ValidatorMessageState.Error as ValidatorMessageState; 将起作用,因为不是打字稿将无法缩小类型。但是如果你只给变量赋值一次,为什么要使用 switch 语句呢?如果操场上的代码只是一个简短的示例,而您的实际代码将有更多的任务,那么它应该可以在没有更改的情况下工作
    • 你是对的,第一个游乐场的代码已经被简化了。我已经在我的帖子末尾放置了第二个游乐场,其中包含我想要在这里实现的目标。基本上,当我遇到更高的严重性时,我会浏览带有状态的消息列表并增加全局严重性。目标是选择一种颜色。
    • 啊,我现在了解您的用例了。实际上,除了let maxStateEncoutered = ValidatorMessageState.Error as ValidatorMessageState; 上面的解决方法之外,这里没有什么可做的(至少据我所知)。github 中描述您的问题的问题:github.com/microsoft/TypeScript/issues/9998(尽管我怀疑它永远不会被修复......)跨度>
    • 感谢您的链接,很高兴看到我不是唯一一个有问题的人。我将提取您在第一个答案中提出的功能。
    猜你喜欢
    • 1970-01-01
    • 2013-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-08
    • 2019-06-07
    • 1970-01-01
    相关资源
    最近更新 更多