【问题标题】:typescript typeof string doesn't work as expected打字稿 typeof 字符串无法按预期工作
【发布时间】:2021-08-19 13:10:43
【问题描述】:

谁能解释为什么第二个变种不起作用?是bug吗?

const prints = (s: string): void => console.log(s);
var x: string | number = Date.now() % 2 ? "test" : 5;

// 1st: working
if (typeof x === "string") {
  prints(x);
}

// 2nd: not working
var typex = typeof x === "string";
if (typex) {
  prints(x);
}

第二个变种显示以下错误:

'string | 类型的参数number' 不可分配给“string”类型的参数。 类型“数字”不可分配给类型“字符串”

TS Playground

【问题讨论】:

  • 这不是错误,但根本不支持。后者的代码流分析会变得太复杂太快。
  • 你可能想看看this issuethis issue
  • @ASDFGerte 你的答案是最好的

标签: javascript string typescript typeof


【解决方案1】:

TypeScript 不够聪明,无法证明第二个if 中的x 确实是string。由于prints 只接受string,它不能证明xstring,所以会报错。

第一种情况,类型检查发生在 if 条件本身内,因为 TypeScript 有 a special case for understanding that kind of type check。但是,理解某个变量中的某些值可以指示某个其他变量的类型,这超出了它可以处理的范围。是的,在这个具体的例子中,它看起来应该是微不足道的,但它很快就会变得非常困难,甚至完全不可能在一般情况下发挥作用。

如果您绝对希望第二种情况起作用,尽管类型检查与 if 是分开的,您需要通过显式转换值来为 TypeScript 提供额外信息。例如,使用prints(x as string) 意味着“我保证它始终是string。如果不是,那么程序爆炸时是我的错。”这种类型的转换是向 TypeScript 发出的一个信号,即开发人员知道一些它不理解的东西并盲目信任它。

【讨论】:

  • 我发现第一个案例甚至有效,这很有趣。您是否碰巧有一个链接,我们可以在其中阅读有关 typescript 如何处理 if 条件的更多信息?
  • 谢谢。该链接很好地解释了打字稿在幕后的作用。 @BambooleanLogic:也许您可以将文档链接添加到您的答案中。
  • @FreemanLambda 它是 TS 的主题之一:typescriptlang.org/docs/handbook/2/narrowing.html
【解决方案2】:

正如 cmets 已经提到的,github 上已经存在这个问题: Indirect type narrowing via constallow storing results of narrowing in booleans for further narrowing

【讨论】:

    猜你喜欢
    • 2020-04-23
    • 2021-06-13
    • 2017-06-10
    • 1970-01-01
    • 1970-01-01
    • 2012-10-31
    • 1970-01-01
    • 1970-01-01
    • 2021-11-30
    相关资源
    最近更新 更多