Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling optional field in Typescript

Following is my React Component code snippet where one of the fields is optional. Being optional, I have to initialize it undefined but this makes it tough to later use it even after type check. I am not sure how to tackle this. I am using typescript version 3.2.2.

interface State {
  open: boolean;
  selected?: SelectedFieldType;
}

class CFilter extends React.Component<Props, State> {
  state = {
    open: false,
    selected: undefined
  };

  onOperatorValueChange = (value: any) => {
    if (typeof this.state.selected !== undefined) {
      console.log(this.state.selected.value); // ERROR: Object is possibly undefined (property): selected undefined
      this.setState({
        selected: {
          ...this.state.selected, // ERROR: Spread types may only be created from object types
          value: value
        }
      });
    }
  };

  render() {
    return (<span>some jsx</span>);
  }
}

If I don't intialize selected, it will throw me an error

Property selected doesn't exist

like image 843
comiventor Avatar asked Dec 07 '25 06:12

comiventor


1 Answers

I don't have react set up so I can't test this, but my guess is that you should annotate the type of state to State when you initialize it, like

  // note the annotation
  state: State = {
    open: false,
    selected: undefined
  };

instead of letting the compiler infer the type. It's quite possible that the compiler thinks that CFilter['state'] is narrower than State (CFilter extends React.Component<Props, State> means state can be any type that extends State.) and that CFilter['state']['selected'] is always undefined. If so, then this.state.selected will always be considered undefined and it's impossible to change that with a null-check (it is unfortunate that the error message complains about it being "possibly" undefined when it thinks it is necessarily undefined, but that's how it is.)

Try the explicit annotation and see if it fixes the problem. Hope that helps. Good luck!

like image 63
jcalz Avatar answered Dec 09 '25 19:12

jcalz