镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Unions of assertion functions do not act as assertion functions #59707

Description

@AlexPaven

🔎 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

Activity

  1. Andarist commented on Aug 21, 2024

    @Andarist
    Contributor

    According to the source code, it's deliberate (link):

    // Constituent type predicates must all have matching kinds. We don't create composite type predicates for assertions.
  2. jcalz commented on Aug 21, 2024

    @jcalz
    Contributor

    If it's not supported it would be nice if it produced an error similar to #33622 instead of just silently failing.

  3. Andarist commented on Aug 21, 2024

    @Andarist
    Contributor

    Ryan Cavanaugh (@RyanCavanaugh) could you clarify what is the bug here? should it work or should it error in a visible way like Joe Calzaretta (@jcalz) is suggesting? I think the latter but it would be great to have confirmation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptDomain: This-TypingThe issue relates to providing types to thisHelp WantedYou can do this

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions