question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[typescript] `ApolloClient.mutate()` type is not consistent and not usable

See original GitHub issue

The type of ApolloClient.mutate() is not consistent with other methods like query() and offers no way to deal with mutations in a type safe way. Here’s the type of mutate<T, TVariables>():

export default class ApolloClient<TCacheShape> implements DataProxy {
    mutate<T, TVariables = OperationVariables>(options: MutationOptions<T, TVariables>): Promise<FetchResult<T>>;
}

Here’s FetchResult<T>:

export declare type FetchResult<C = Record<string, any>, E = Record<string, any>> = ExecutionResult & {
    extensions?: E;
    context?: C;
};

Note that the T in mutate<T>() corresponds to C in FetchResult<C = Record<string, any>, E = Record<string, any>>. In other words mutate<T>(...).context : T which doesn’t match ApolloClient.query().

Moreover there’s no way to type the resulting data that comes out of the mutation: Because no type parameters are passed to ExecutionResult there’s no way to type mutate(...).data!

And for reference, here’s ExecutionResult from @types/graphql:

export interface ExecutionResult<TData = ExecutionResultDataDefault> {
    errors?: ReadonlyArray<GraphQLError>;
    data?: TData;
}

See also https://github.com/apollographql/apollo-client/issues/4153.

Intended outcome: A consistent, clean way to type graphql queries and mutations.

Actual outcome: Unhelpful and inconsistent types on ApolloClient.mutate() relative to the other methods, query() etc.

How to reproduce the issue: Look at the code.

Versions “apollo-boost”: “0.1.22”

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:5
  • Comments:13 (1 by maintainers)

github_iconTop GitHub Comments

25reactions
Veetahacommented, Nov 29, 2018

Come on, this issue has been being openned since Dec 29, 2017. God damn, can someone fix this bug already?

19reactions
ekroncommented, Mar 29, 2019

The problem is the ApolloClient.mutate function can return Promise<any> even if the correct types are provided as generics.

Example:

interface SampleMutationResult {
  id: string;
}

interface SampleMutationVariables {
  someVariable: string;
}

const result = await client.mutate<SampleMutationResult, SampleMutationVariables>({
  mutation: TaskByIdDocument,
  variables: { someVariable: "test" }
});

// Expect: result to be FetchResult<SampleMutationResult, Record<string, any>>

// Actual: result is type any.

The fix is to add the typings for graphql module:

yarn add @types/graphql

What’s the problem?

I’ll take a quick guess. The ApolloClient type returns a FetchResult for mutate:

mutate<T = any, TVariables = OperationVariables>(options: MutationOptions<T, TVariables>): Promise<FetchResult<T>>;

FetchResult relies on a typing being present for ExecutionResult from the graphql package:

export declare type FetchResult<TData = {
    [key: string]: any;
}, C = Record<string, any>, E = Record<string, any>> = ExecutionResult<TData> & {
    extensions?: E;
    context?: C;
};

Possibly if the @types/graphql typings are not available then you’ll get the unexpected Promise<any> returned from mutate?

Read more comments on GitHub >

github_iconTop Results From Across the Web

TypeScript with Apollo Client - Apollo GraphQL Docs
This function enables us to type the variables that go into our React hooks, along with the results from those hooks. useQuery. Below...
Read more >
What is the TypeScript type of failed useMutation requests?
After having a quick look at the source code of the function, it seems like it throws an ApolloError, which, according to this...
Read more >
GraphQL Mutations and Caching using Apollo Client
First we write the GraphQL mutation that we want to execute, using the gql symbol. ... or if it creates or deletes entities,...
Read more >
Getting started with Apollo + GraphQL in Angular - Briebug Blog
If you are working within an NX repository or have a non-standard Angular repository ... How to write GraphQL Query / Mutation definitions....
Read more >
Apollo Codegen In React - Generate Typescript ... - YouTube
When working with GraphQL and Typescript in React, ... a type or an interface as a generic inside your useQuery () or useMutation...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found