【问题标题】:Broken switch statement in TypeScriptTypeScript 中的 switch 语句损坏
【发布时间】:2020-01-14 19:33:38
【问题描述】:

我在 TypeScript 中遇到 switch 语句的问题

在多个代码编辑器上尝试过,我正在尝试使用 switch (true),但由于某种原因,代码在 switch 语句中失败。

const todoList: string[] | null = [];

function pushItemToTodoList(item: string) {
  //COMPILES!!
  if (todoList !== undefined && todoList !== null && todoList.length) {
    if (todoList.length >= 5) {
      console.log("LIST IS FULL!");
    }
  }

  //DOESN'T COPMILE!!
  switch (true) {
    case todoList !== undefined && todoList !== null && todoList.length:
      if (todoList.length >= 5) { //todoList is null???
        console.log("LIST IS FULL!");
      }
      break;
  }
}

pushItemToTodoList("clean house");

here is a picture of the error, thank you

【问题讨论】:

  • 你得到的错误是什么?
  • 我看不出使用 switch 有什么用,也不是你如何使用它。您可以解释您要达到的目标,以便得到解答。
  • @MarkusZeller 这有点像 hack,但它是有效的用法。由于您通常执行switch (x),然后尝试将x 匹配到每个case,您也可以传递true,然后期望每个case 评估为truefalse。理想情况下,您将拥有多个相互排斥的 case 语句。我不认为这是一种好的技术,但它是编写switch的一种可能方式。
  • @MarkusZeller 这不是 && 的工作方式:它永远不会到达那个块。它使用严格的平等,而不是真实性,它评估为一个数字(todoList.length)而不是布尔值true
  • @JaredSmith 或 todoList!.length >= 5

标签: javascript typescript


【解决方案1】:

switch 语句本身不会失败。 它 simpy 不容忍带有变量的 case 语句。也不是条件运算符,只有静态值。 在编译时,switch 语句为 case 语句中的所有静态值及其跳转位置建立索引。 您不能在 case 语句中使用变量,因为在编译时,这些变量不应该被计算甚至不存在。 Switch - Case 语句非常高效,因为具有静态值和跳转位置的索引被预编译。 不过,有一种方法可以解决这个特定问题,将布尔逻辑与 switch 语句中的代数和 case 语句中的静态值结合起来。

【讨论】:

  • 这与问题无关,您描述的是 switch 在 c 中的工作方式,而不是 Typescript。我可以向你保证,switch 在 typescript 编译时确实可以容忍正确类型的变量。
  • 您能否阐明正确类型的变量的含义?你的意思是 switch 语句中的结果必须与 case 语句中的值具有相同的类型?
  • Typescript 编译器does not compile the switch into a jump table at compile time。您正在考虑 C。因此,在 case 语句中使用变量是完全有效的,只要它们具有正确的类型。您的回答实际上是错误的。
  • OP 的实际问题是他们没有使用 proper type guard syntax 来满足编译器认为数组不为空,并且 && 运算符返回表达式的最后一个真值,在这种情况下是一个数字(列表长度),它并不严格等于 boolean true(打开的值),因此永远不会到达 case 语句。
【解决方案2】:

这不是 switch 语句的工作方式。

如果你会写:

switch (true) {
    case todoList:
      if (todoList.length >= 5) { //todoList is null???
        console.log("LIST IS FULL!");
      }
      break;
  }

它会起作用,因为在 switch 语句中你正在检查 case 是否为真。

Switch 语句采用原始值,例如布尔值、字符串、数字等。

您尝试使用 switch 语句的方式更复杂,并且只能使用 if 语句。

【讨论】:

  • 从技术上讲,这并没有错……但它仍然完全没有意义。仍然没有理由在这里使用switch 而不是if 声明。
  • "Switch 语句采用原始值,例如布尔值、字符串、数字等",而这个switch 确实采用原始true。您可能指的是 case 语句,但它们实际上可以采用任何将与传递给switch 的表达式进行比较的表达式。因此,如果您执行switch (true) 并且case 语句条件之一的计算结果为true,那么它将被触发。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-09-23
  • 2013-05-11
  • 2020-02-14
  • 2021-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多