GraphQL Code Generator creates this type on the top of the created TypeScript file:
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
and uses it for all client created query variables:
src/foo.graphql
:
query Foo($id: ID!) {
foo(id: $id) {
bar
}
}
generated/foo.ts
:
...
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
...
export type FooQueryVariables = Exact<{
id: Scalars['ID'];
}>;
...
What is the purpose of this Exact<T>
type and how does it affect FooQueryVariables
(vs. if it would not be there)?
Full demo for https://www.graphql-code-generator.com/#live-demo:
schema.graphql
:
schema {
query: Query
}
type Query {
foo(id: ID!): Foo
}
type Foo {
bar: String!
}
operation.graphql
:
query Foo($id: ID!) {
foo(id: $id) {
bar
}
}
codegen.yml
:
generates:
operations-types.ts:
plugins:
- typescript
- typescript-operations
Generated operations-types.ts
:
export type Maybe<T> = T | null;
export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };
export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };
/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
ID: string;
String: string;
Boolean: boolean;
Int: number;
Float: number;
};
export type Query = {
__typename?: 'Query';
foo?: Maybe<Foo>;
};
export type QueryFooArgs = {
id: Scalars['ID'];
};
export type Foo = {
__typename?: 'Foo';
bar: Scalars['String'];
};
export type FooQueryVariables = Exact<{
id: Scalars['ID'];
}>;
export type FooQuery = { __typename?: 'Query', foo?: Maybe<{ __typename?: 'Foo', bar: string }> };
It aims to make it so that one cannot pass an object with any additional properties (in addition to id
) as FooQueryVariables
. But it fails to do so: https://github.com/dotansimha/graphql-code-generator/issues/4577