Skip to content

Method return type cannot be used as discriminant #49771

Open
@kyranet

Description

@kyranet

Bug Report

When having objects with methods that return a boolean, the types don't get narrowed when checked, contrary to properties.

🔎 Search Terms

type guard, narrowing

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about type narrowing with methods returning strict literals in the types

⏯ Playground Link

Playground link with relevant code

💻 Code

class Some<T> {
  public readonly value: T;
  public constructor(value: T) {
    this.value = value;
  }

  public isSome(): true { return true; }
}

class None {
  public isSome(): false { return false; }
}

type Option<T> = Some<T> | None;

declare const x: Option<string>;

if (x.isSome()) {
  x.value;
  // Property 'value' does not exist on type 'Option<string>'.
  //   Property 'value' does not exist on type 'None'.(2339)
}

🙁 Actual behavior

isSome() does not narrow the type from Option<string> to Some<string> unless the return type of isSome() in either or both classes are typed as this is Some<T>:

Some#isSome() None#isSome() Narrows?
true false
this is Some<T> false
true this is Some<any>
this is Some<T> this is Some<any>

This behaviour is not consistent to the one when typed properties (public some: true = true/public some: false = false) are used, where the type narrowing system works perfectly fine.

🙂 Expected behavior

isSome() would be sufficient to narrow Option<string> to Some<string>, as is the case with regular properties (Playground link). In short, the first case in the aforementioned table should work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Awaiting More FeedbackThis means we'd like to hear from more people who would be helped by this featureSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions