Microsoft/TypeScript

Unions of assertion functions do not act as assertion functions

Open

#59,707 建立於 2024年8月21日

在 GitHub 查看
 (3 留言) (0 反應) (0 負責人)TypeScript (6,726 fork)batch import
BugDomain: This-TypingHelp Wanted

倉庫指標

Star
 (48,455 star)
PR 合併指標
 (平均合併 6天 17小時) (30 天內合併 9 個 PR)

描述

🔎 Search Terms

narrowing, assertion function

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about everything

⏯ Playground Link

https://tsplay.dev/Wv3DYw

💻 Code

  class box<T> {
    constructor(public value: T){}

    check(): this is box<string> {
      return typeof this.value == 'string';
    }

    assert(): asserts this is box<string> {
      if (typeof this.value != 'string') throw new Error();
    }

    private test() {
      this.assert();
      // type correctly narrowed
      this.value.substring(0);
    }
  }

  function make() : box<string> | box<number> {
    return new box('a');
  }

  function assert(b: box<string> | box<number>): asserts b is box<string> {
    if (typeof b.value != 'string') throw new Error();
  }

  const b = make();

  if (b.check()) {
    // type correctly narrowed
    b.value.substring(0);
  }

  b.assert();

  // type not narrowed (substring does not exist on type 'string | number')
  b.value.substring(0);
   
  assert(b);

  // type correctly narrowed
  b.value.substring(0);

🙁 Actual behavior

Type is not narrowed after method call

🙂 Expected behavior

I expected the type to be narrowed after method call since it is narrowed within other methods or when using a function external to the type.

Additional information about the issue

https://stackoverflow.com/questions/78879014/typescript-type-assertion-does-not-narrow-class-instance-from-union

貢獻者指南