Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
AlexPaven opened this issue Aug 21, 2024 · 3 comments
Open

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

AlexPaven opened this issue Aug 21, 2024 · 3 comments
Labels
Bug A bug in TypeScript Help Wanted You can do this
Milestone

Comments

@AlexPaven
Copy link

πŸ”Ž 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

@Andarist
Copy link
Contributor

Andarist commented Aug 21, 2024

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.

@jcalz
Copy link
Contributor

jcalz commented Aug 21, 2024

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

@RyanCavanaugh RyanCavanaugh added Bug A bug in TypeScript Help Wanted You can do this labels Aug 21, 2024
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Aug 21, 2024
@Andarist
Copy link
Contributor

Andarist commented Aug 21, 2024

@RyanCavanaugh could you clarify what is the bug here? should it work or should it error in a visible way like @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
Labels
Bug A bug in TypeScript Help Wanted You can do this
Projects
None yet
Development

No branches or pull requests

4 participants