Skip to content

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

@AlexPaven

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

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