question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Strange boolean-discriminant narrowing with strictNullChecks off

See original GitHub issue

TypeScript Version: nightly (2.1.0-dev.20160826)

Code

type Result = { success: true }
            | { success: false, error: string }

function handleError(res: Result) {
    if (res.success === true) {
        return;
    }

    res.error; // OK
}

function handleError2(res: Result) {
    if (res.success !== false) {
        return;
    }

    res.error; // OK
}

function handleError3(res: Result) {
    if (res.success) {
        return;
    }

    res.error; // Property 'error' does not exist on type 'Result'
               // but should be OK
}

Expected behavior: All three cases should behave the same.

Issue Analytics

  • State:open
  • Created 7 years ago
  • Reactions:6
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

3reactions
haltman-atcommented, Sep 3, 2019

Hey, I just wanted to point out that this issue now has additional relevance in TypeScript 3.6 due to the addition of the Generator type and the new IteratorResult type. I was writing some code with generators, expecting I could use while(!result.done) to loop over the case where the generator was not done, but found in fact I had to use while(result.done === false). Might be a reason to revisit this?

0reactions
Tanja-4732commented, Jul 25, 2020

I have experienced similar behaviour, and the following code helped me to work around this limitation:

(Assuming we have foo with the discriminating boolean-property “discBool” and the optional property “optionalProperty” which is only present in one of the two sub-types of foo’s super-type. In other words: If discBool is false, optionalProperty is present, if discBool is true, optionalProperty is not present in foo)

switch (foo.discBool) {
  case false:
    doSomething(foo.optionalProperty);
}

while this code didn’t work:

if (!foo.discBool) {
  doSomething(foo.optionalProperty); // Error here
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

strictNullChecks - TSConfig Option - TypeScript
When strictNullChecks is false , null and undefined are effectively ignored by the language. This can lead to unexpected errors at runtime.
Read more >
Refactoring Octopus: Adding strict null checks to the Octopus ...
Learn from some of the lessons we learned adding strict null checks to the Octopus front-end codebase.
Read more >
Handbook Page - Microsoft Open Source
strictNullChecks off ; strictNullChecks on; Non-null Assertion Operator (Postfix ! ) ... Narrowing occurs when TypeScript can deduce a more specific type for...
Read more >
typescript not null type guard - La Columnaria Blog
Previously, we discussed how all type guards are based around a boolean check. ... The reason why this doesn't work when strictNullChecks is...
Read more >
Overview - TypeScript
Below, next() can only be called with boolean s, and depending on the value ... In TypeScript 3.5, when assigning to types with...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found