Writing the below in typescript complains with 'variables' does not exist in type 'Query | Mutation'
let client = createTestClient(server);
let result = await client.query({
query: SOME_QUERY,
variables: { var: "var" }
});
Looking in createTestClient.ts shows that client.query is written
({ query, mutation, ...args }: Query | Mutation) => { ... }
with
type Query = { query: StringOrAst; mutation?: undefined };
type Mutation = { mutation: StringOrAst; query?: undefined };
As it is currently written args is later passed through correctly to server.executeOperation, however the typings imply that args can only ever be an empty object when in fact it should allow the following additional fields (from the interface GraphQLRequest in requestPipelineAPI.ts)
{
operationName?: string;
variables?: { [name: string]: any };
extensions?: Record<string, any>;
http?: Pick<Request, 'url' | 'method' | 'headers'>;
}
It may be a good idea to implement it like this
type RequestNoQuery = Pick<GraphQLRequest, Exclude<keyof GraphQLRequest, "query">>;
type Query = { query: StringOrAst; mutation?: undefined } & RequestNoQuery;
type Mutation = { mutation: StringOrAst; query?: undefined } & RequestNoQuery;
So as to be less coupled to any changes to GraphQLRequest
It would be great if the variables type was a generic (as well as the return type), just like apollo-client is doing it.
query<T, TVariables = OperationVariables>(options: QueryOptions<TVariables>): Promise<ApolloQueryResult<T>>;
As a workaround, you can add a apollo-server-testing.d.ts file to your project with the following:
declare module 'apollo-server-testing' {
import { ApolloServerBase } from 'apollo-server-core';
import { print, DocumentNode } from 'graphql';
import { GraphQLResponse } from 'graphql-extensions';
type StringOrAst = string | DocumentNode;
// A query must not come with a mutation (and vice versa).
type Query<TVariables> = {
query: StringOrAst;
mutation?: undefined;
variables?: TVariables;
};
type Mutation<TVariables> = {
mutation: StringOrAst;
query?: undefined;
variables?: TVariables;
};
export const createTestClient: <TVariables>(
server: ApolloServerBase,
) => {
query: (query: Query<TVariables>) => Promise<GraphQLResponse>;
mutate: (mutation: Mutation<TVariables>) => Promise<GraphQLResponse>;
};
}
Most helpful comment
As a workaround, you can add a
apollo-server-testing.d.tsfile to your project with the following: