Why data is optional?

Hello guys!

For sake of type compability could anybody explain why data property of FetchResult is optional?

export interface FetchResult<TData = {
    [key: string]: any;
}, C = Record<string, any>, E = Record<string, any>> extends ExecutionResult {
    data?: TData | null;
    extensions?: E;
    context?: C;
}

In which cases it’s possible? And how is it supposed to work with it?

@qodunpob Apollo Client’s FetchResult type mirrors the graphql-js ExecutionResult type:

data has been optional in graphql-js since its inception:

Are you running into a specific issue because of this?

Oh, thank you, that slightly explains. But it is still not clear under what situations this can happen and how to work with it in “strict” mode. I mean in “strict” mode you have to take care about handling optional state.

I’m not running into any issues except that it seems like when using useMutation, data returned from the mutate function will always be defined, because errors are thrown, which makes me need use a non-null assertion on result data (or test for TS knowing it’s actually there), which is undesirable?

  const [doThing] = useMutation(doThingMutation);

  // later...

  try {
    const {data} = await doThing({
      variables: {
        email: form.values.email,
      },
    });
    // Here `data` is not `undefined`, because when there are errors, 
    // they are thrown and caught below. But I have to use a `!`.
    console.log(data!.field)
  } catch (e) {
    if (
      e instanceof ApolloError &&
      e.graphQLErrors[0].extensions.code === 'foo'
    ) {
      setFooError(true);
    } else {
      setError(true);
    }
  }

@ dminkovsky based on your errorPolicy, you can run into situations where data is actually undefined (because you have an error, but prevent it from throwing).