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

Type not narrowed by === when equivalent type guard works #36772

Open
kaya3 opened this issue Feb 13, 2020 · 1 comment
Open

Type not narrowed by === when equivalent type guard works #36772

kaya3 opened this issue Feb 13, 2020 · 1 comment
Assignees
Labels
Bug A bug in TypeScript Rescheduled This issue was previously scheduled to an earlier milestone

Comments

@kaya3
Copy link

kaya3 commented Feb 13, 2020

TypeScript Version: 3.7.5, also tested on 3.9.0-dev.20200212

Search Terms: equals, type guard, type parameter, narrowing

Code

type AorB = 'a' | 'b';

function isA(t: AorB): t is 'a' {
  return t === 'a';
}

function test<T extends AorB>(arg: T) {
  if (isA(arg)) {
    let a1: T & 'a' = arg; // ok
  }
  if (arg === 'a') {
    let a2: T & 'a' = arg; // error
  }
}

Expected behavior: The condition arg === 'a' should narrow the type of arg to T & 'a' in the second if block, in the same way as the equivalent type guard function does.

Actual behavior: The type of arg is not narrowed in the second if block.

Playground Link: Playground Link

Related Issues: N/A

@maciejsikora
Copy link

Ok so the following question is related to this - https://stackoverflow.com/questions/60204107/typescript-doesnt-infer-correct-type-with-generic-extending-string-union-type/60206029#60206029.

As I assume what is happening here is that the condition is valid, as it has no error-prone runtime effect, but the typeguard is not applied by it. And the reason why the condition doesn't work as typguard is a fact that typeguard can work only forall members. Below equivalent typeguard:

function guard<X extends AorB , Y extends AorB >(x: X, y: Y): x is Y { return x == y } // error

It means that conditions behave as typeguards only if left and right side of the condition overlap.
And here we can have situation when provided type doesn't overlap (X can be 'a', Y can be 'b').
Is this assumption correct? I cannot find any information about that in language specification.

@RyanCavanaugh RyanCavanaugh added this to the TypeScript 5.5.0 milestone Mar 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Rescheduled This issue was previously scheduled to an earlier milestone
Projects
Design Meeting Docket
  
Awaiting triage
Development

No branches or pull requests

5 participants