【问题标题】:What is the difference between "asserts value is type" and "value is type" in TypeScript?TypeScript 中“断言值是类型”和“值是类型”有什么区别?
【发布时间】:2023-02-18 15:25:23
【问题描述】:

TypeScript 具有 is 运算符,可帮助创建用于类型检查的测试函数。最近我看到了这个运算符的两种不同实现,其中一种使用了asserts关键字。

我没有在文档中找到有关两种使用方式差异的信息。我试了一下,如果我是对的,asserts 不会让你从函数返回任何东西,但除此之外我没有发现任何区别。

这是我测试过的代码:

// Asserts and tests the value without returninng anything
function assertIsString(value: unknown): asserts value is string {
  if (typeof value !== "string") throw Error("value is not a string");
}

// Tests the value and returns something so it can be used for typecheck
// more explicitly
function testIsString(value: unknown): value is string {
  return typeof value === "string";
}

const string = "hello";
const number = 123;

assertIsString(string); // does nothing
assertIsString(number); // throws Error
testIsString(string); // returns true
testIsString(number); // returns false

问题:这两个用例之间还有其他区别吗?

【问题讨论】:

    标签: javascript typescript types assertion typechecking


    【解决方案1】:

    简介:主要区别在于一个抛出而另一个必须在条件中使用。


    可能抛出异常并返回void 的函数称为assertion functions

    这些做出断言(您可能认为它是与编译器创建契约),即如果函数不抛出异常,则返回值中的谓词将为真。从那时起(在当前范围内),谓词中的类型信息将生效。


    返回boolean值的函数称为type predicates

    而不是潜在地抛出异常(并导致您的程序停止,除非它被捕获 - 请参阅try...catch),它们只是返回一个布尔值。如果布尔值为真,则对于调用谓词的范围的其余部分(例如代码块),谓词将生效。


    文档链接针对每种情况(和其他信息)提供了多个示例。这是一个演示:

    TS Playground

    // predicate
    function exists <T>(maybe: T): maybe is NonNullable<T> {
      return maybe != null;
    }
    
    // assertion
    function assertExists <T>(maybe: T): asserts maybe is NonNullable<T> {
      if (maybe == null) throw new Error(`${maybe} doesn't exist`);
    }
    
    function example1 () {
      console.log('example1 begin');
      let maybe: string | undefined;
    
      if (exists(maybe)) { 
        maybe; // string
      }
      else {
        maybe; // undefined
      }
    
      console.log('example1 end');
    }
    
    function example2 () {
      console.log('example2 begin');
      let maybe: string | undefined;
    
      assertExists(maybe);
    
      maybe; // string
    
      console.log('example2 end');
    }
    
    example1(); // 'example1 begin' then 'example1 end'
    example2(); // only 'example2 begin', then exception is thrown: `undefined doesn't exist`
    
    

    【讨论】:

    • 令人惊奇的是,一个人每天都可以通过在 SO 上闲逛来学习新东西 =)
    • @MatthieuRiegler 您应该在 TS 存储库中的 issues 周围转转! (该链接是按大多数 ? 反应排序的视图)。
    猜你喜欢
    • 2013-12-27
    • 2010-12-11
    • 2018-12-10
    • 2011-09-12
    • 2016-10-09
    • 1970-01-01
    • 2011-06-30
    • 2018-10-05
    • 2011-02-11
    相关资源
    最近更新 更多