Optional chaining, proper infer in type guard
See original GitHub issueTypeScript 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:
- Created 4 years ago
- Reactions:16
- Comments:7 (3 by maintainers)
Top 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 >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
Top Related Hashnode Post
No results found
This might be more tractable to fix now that
NonNullable
has a simpler definitionThis is a little tricky; TS sees the
x is NonNullable<A>
as an opaque treatment of the type ofA
. As humans we know that ifx?.y?.z
isn’tundefined/null
, thenx.y
can’t beundefined/null
, but TS doesn’t have a way to apply that knowledge through thex is NonNullable<A>
check becausex 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.