Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't TypeScript see that a nested value cannot be undefined?

TypeScript should be able to infer from a ternary operator that a specific nested value cannot be undefined. But it does not. It only works if I insert the null-assertion operator ! into the code to indicate that a value is not null or undefined.

I have a functional react component with a props interface with an accounts field.

export interface IAccountState {
  [key: string]: {
    address?: string;
  };
}

accounts: IAccountState;

In the return statement I have a ternary operator that checks if the value is undefined.

{!this.props.accounts[this.props.network] || this.props.accounts[this.props.network].address === undefined ? (
<div/>) : (
  <OtherComponent
    address={this.props.accounts[this.props.network].address}
  />
)

Here I get the error.

Type 'string | undefined' is not assignable to type 'string'.
  Type 'undefined' is not assignable to type 'string'.ts(2322)

But I think the TypeScript compiler should be able to see that the address value cannot be undefined due to the ternary operator.

I use TypeScript 3.9.7 and my tsconfig.json has "strictNullChecks": true set.

like image 648
Thorkil Værge Avatar asked May 25 '26 01:05

Thorkil Værge


1 Answers

Your best bet here is to give TypeScript something more specific to narrow the type of. Prior to that JSX expression:

const address = this.props.accounts[this.props.network]?.address;

Or without the new[ish] optional chaining operator:

const address = this.props.accounts[this.props.network] && this.props.accounts[this.props.network].address;

Then in the JSX expression:

{address === undefined ? (
<div/>) : (
  <OtherComponent
    address={address}
  />
)

Here's a playground link replicating the problem you're having with a simpler example, and here's one showing that saving to a const solves it.

like image 148
T.J. Crowder Avatar answered May 27 '26 15:05

T.J. Crowder