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.

Optional chaining, proper infer in type guard

See original GitHub issue

TypeScript Version: 3.7.0

Search Terms: optional chaining

Code

type X = {
  y?: {
    z?: string
  }
}
const x: X = {
  y: {
  }
}
// type guard
function isNotNull<A>(x: A): x is NonNullable<A> {
  return x!== null && x!== undefined;
}
// function which I want to call in the result of the expression
function title(str: string) {
  return str.length > 0 ? 'Dear ' + str : 'Dear nobody';
}

isNotNull(x?.y?.z) ? title(x.y.z) : null // type error - object is possibly undefined

The code fix is by adding additional checks or additional temporary variables:

(x?.y?.z && isNotNull(x.y.z)) ? title(x.y.z) : null
// or
const tmp = x?.y?.z
isNotNull(tmp) ? title(tmp) : null

Expected behavior: TypeScript is able to infer that optional chaining was used as an argument, what means that typeguard is checking the whole chain.

Actual behavior: TypeScript needs a code change in order to understand that optional chaining already checked other values from being null | undefined.

Issue Analytics

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

github_iconTop GitHub Comments

3reactions
RyanCavanaughcommented, Aug 31, 2022

This might be more tractable to fix now that NonNullable has a simpler definition

3reactions
RyanCavanaughcommented, Nov 8, 2019

This is a little tricky; TS sees the x is NonNullable<A> as an opaque treatment of the type of A. As humans we know that if x?.y?.z isn’t undefined/null, then x.y can’t be undefined/null, but TS doesn’t have a way to apply that knowledge through the x is NonNullable<A> check because x is NonNullable<A> is just some generic type that happens to produce some value, not a special check that changes the types of the subexpressions that produced its type argument.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to use Optional chaining correctly in the unknown
Unfortunately, you cannot do it this simply right now, typescript isn't able to infer types from the in operator very well at the...
Read more >
Documentation - Advanced Types - TypeScript
It just so happens that TypeScript has something called a type guard. ... you can use optional chaining to simplify working with nullable...
Read more >
narrowing types via type guards and assertion functions - 2ality
In TypeScript, a value can have a type that is too general for some operations – for example, a union type. This blog...
Read more >
Filtering arrays with TypeScript type guards - Spencer Miskoviak
However, it can be tricky to properly reflect this in the type system. ... The undefined is handled by using optional chaining (...
Read more >
Filtering Types with Correct Type Inference in RxJs - Medium
Option 2: Define a Type Guard ... .subscribe(event => console.log(event.position));. Now, in subscribe, the event is correctly inferred of type Observable<Scroll> ...
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 Hashnode Post

No results found