Home > Enterprise >  TypeScript, if clause of prop in React with differene types and if statements
TypeScript, if clause of prop in React with differene types and if statements

Time:10-01

I just started with TypeScript and I'm in progress with moving my React app to TypeScript but I have encountered a problem which I'm unable to understand.

It's in my Error component which takes a prop named Error with the type of ApolloError which in it's turn has a variable called networkError which can be of 4 different types Error | ServerParseError | ServerError | null so in my code I handle all of these cases with if statemens like this:

if (
    error.networkError &&
    error.networkError.result &&
    error.networkError.result.errors &&
    error.networkError.result.errors.length
) {
    const errors = error.networkError.result.errors.map((err) => {
        const { message, locations, path } = err;
        return (
            <div key={err.path}>
                <p>
                    <strong>[Network error]:</strong>
                    Message: {message}
                </p>
            </div>
        );
    });
}

This worked good with plain JavaScript but in TypeScript this results in a build error with the error:

Property 'result' does not exist on type 'Error | ServerParseError | ServerError'.
  Property 'result does not exist on type 'Error'

Which I understand since result is only a part of ServerError. But I don't know how to tell that in this if clause I want to handle Server Errors f.ex.

Any idea? I'm pretty new so I probably missed something basic.
Hope my question is clear.

CodePudding user response:

To reference a property that might not exist, you need to check if it's present first. This will narrow the type and then Typescript will allow you access the property because you proved it exists at runtime.

You can do that with the in operator.

if (
  error.networkError &&
  'result' in error.networkError &&
  error.networkError.result &&
  error.networkError.result.errors &&
  error.networkError.result.errors.length
) {

See playground which has incomplete types because you didn't include them in the question.

  • Related