【问题标题】:what's the point to use non-null assertion?使用非空断言有什么意义?
【发布时间】:2019-09-16 16:04:38
【问题描述】:

我是打字稿的新手,我的教科书说:

只有在您知道不会出现空值时才应使用非空断言。如果您应用断言并且确实出现空值,则会导致运行时错误。

所以我写了一个简单的打字稿文件来验证(使用“strictNullChecks”:true):

function calculateTax(amount: number, format: boolean): string | number | null {
    if (amount === 0) {
        return null;
    }
    const calcAmount = amount * 1.2;
    return format ? `$${calcAmount.toFixed(2)}` : calcAmount;
}
let taxValue: string | number = calculateTax(0, false)!;

以下是我的问题:

Q1-我们可以看到calculateTax(0, false)会返回null,我运行程序后,完全没有运行时错误?为什么作者说会有运行时错误?

Q2-我可以将没有非空断言的语句重写为:

let taxValue: string | number = calculateTax(0, false);

它没有编译错误和运行时错误,完美运行,那么使用非空断言有什么意义呢?

【问题讨论】:

  • 如果您对null 进行操作,会出现运行时错误。 TS 编译为 JS,所以很自然地你可以拥有nulls 并且仅仅存在一个不会造成问题。但是calculateTax(0, false).toString() 会导致 TypeError。
  • 至于第二季度 - 你可以,但仍然可以返回 null,所以不仅仅是 stringnumber
  • @VLAZ 我知道calculateTax(0, false).toString() 会导致 TypeError。所以我们只需要使用 typeof 来说明,这正是我的问题,如果你仍然需要手动检查它,那么使用非 null 断言有什么意义呢?
  • 非空断言适用于当您作为程序员知道您不会得到null 但TS 无法解决的情况。例如,您执行calculateTax(userInput, false),这可能导致nulluserInput = 0,但您实际上是在该值到达代码的那个点之前过滤该值。 TS 无法解决这个问题(例如,它不知道您的验证逻辑),但它知道结果可能null。然而,你知道你永远不会有userInput = 0,所以你可以告诉 TS。

标签: javascript typescript


【解决方案1】:

我猜你误解了类型断言的作用。这不是编译器确保的事情,它是一种“弃权”,你给编译器说“我在此放弃检查这种类型的权利,我保证它在运行时会是 X 并且我对后果负责,如果它不是”。

通过使用! 断言,您基本上是在告诉编译器“闭嘴,我知道得更好,这永远不会为空”。编译器别无选择,只能同意你的意见,但如果你不遵守承诺(你没有遵守),运行时错误就迫在眉睫。

显然,类型断言几乎从来都不是一个好主意。最后,Typescript 的重点是静态检查你的类型。在将!as 随意放置之前请三思。

【讨论】:

    【解决方案2】:

    如果使用--strictNullChecks 运行编译,则会出现编译错误

    error TS2531: Object is possibly 'null'.
    

    应该提高。我猜作者的意思是,如果您继续使用假定为非空的对象,非空断言会导致运行时异常。

    例如,在上面的示例中使用非 null 断言调用 taxValue 上的函数不会警告您该值可能为 null,但如果它为 null 并且您在运行时调用该函数,它将引发异常。

    非空断言可用于消除虚假警告,即类型可能为空的已知非空变量可以像不可空一样使用。

    【讨论】:

      猜你喜欢
      • 2022-11-22
      • 1970-01-01
      • 2018-07-03
      • 2020-10-09
      • 1970-01-01
      • 2019-02-22
      • 2021-01-08
      • 1970-01-01
      • 2010-11-08
      相关资源
      最近更新 更多