Reputation: 4122
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
Upvotes: 3
Views: 3070
Reputation: 1398
Type 'null' is not assignable to type 'SelectedFieldType | undefined' sounds odd... maybe you could try to add just for testing a pipe allowing null value to SelectedFieldType. But it is bizarre to have to do it.
interface State {
open: boolean;
selected?: SelectedFieldType | null;
}
The observation from @jcalz also seems very good. You should try it.
If it don't work, you could try to re-write your code to something like:
class CFilter extends React.Component {
state: State = {
open: false,
selected: null,
};
onOperatorValueChange = (value: any) => {
if (this.state.selected) {
this.setState({
selected: {
...this.state.selected,
value
}
});
}
};
I have tested on this stackblitz and it seems to work fine with no errors.
Upvotes: 0
Reputation: 327624
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!
Upvotes: 4