Graphql-code-generator: Incorrect no-variables type

Created on 28 May 2020  路  22Comments  路  Source: dotansimha/graphql-code-generator

Describe the bug
If query takes no arguments, its variables generates as {}, which means any non-nullish value
So we can use it like this

useQueryWithoutVariables({variables: "any value"})
  1. My GraphQL schema:
type Query {
    user(id: ID!): User!
}
  1. My GraphQL operations:
query user {
    user(id: 1) {
        id
        username
        email
    }
}
  1. My codegen.yml config file:
schema: schema.graphql
documents: document.graphql
generates:
  types.ts:
    plugins:
      - typescript
      - typescript-operations

Expected behavior
No variables allowed, type should be never

enhancement plugins waiting-for-release

Most helpful comment

Fixed in v1.15.3.

All 22 comments

Where do you have this function? useQueryWithoutVariables
Those two plugins don't generate this kind of functions;

      - typescript
      - typescript-operations

It's from typescript-react-apollo
By the way, I can use useQuery hook from @apollo/client without other plugins like this

useQuery<UserQuery, UserQueryVariables>(gql`...`, { variables: 1 })

You are right @oceandrama . And suggestion for a solution for that?
I was thinking about doing something like that to make sure no additional keys are being added, and this way we can really validate the exact shape of the variables type.

@dotansimha LGTM

I'm not sure where to apply it, because we can't use Exact (type Exact<T, R> = T extends R ? R extends T ? T : never : never) over the original variables type, since it requires the function call to get the T (the actual passes variables).

In this case I guess we'll need to modify it on the level of the function call (hooks/hoc/components, and in each plugin - react / apollo / others).

@kamilkisiela @ardatan what do you think?

@dotansimha or like this

We know in advance if there are variables or not

Thanks @kamilkisiela . I created a PR for wrapping all variables in Exact type:
https://github.com/dotansimha/graphql-code-generator/pull/4194

@oceandrama can you please try the alpha version? 1.15.2-alpha-0b6c3cb0.0

@dotansimha I've tried both alpha-0b6c3cb0.0 and alpha-a841e8b0.0 and saw no changes

"devDependencies": {
    "@graphql-codegen/cli": "^1.15.2-alpha-0b6c3cb0.0",
    "@graphql-codegen/typescript": "^1.15.2-alpha-0b6c3cb0.0",
    "@graphql-codegen/typescript-operations": "^1.15.2-alpha-0b6c3cb0.0",
    "@graphql-codegen/typescript-react-apollo": "^1.15.2-alpha-0b6c3cb0.0",
"@graphql-codegen/cli": "canary"

works, but I still have

export type MeQueryVariables = {};

all other types of query variables with some fields are wrapped by Exact

@oceandrama all your @graphql-codegen/... packages should use the same version.

Btw, we released a stable version with this fix - it's v1.15.2. If you are still having issues, please let us know, and please share a reproduction.

@dotansimha wait, wait, wait. It doesn't work. I've tested alpha-version and wrote that Exact is wrapping only types with some fields. I still have just {} in query without variables. Why did you release that?

@oceandrama I thought you had a missmatch with versions, didn't notice that {} it not being wrapped (in case there are no vars at all).
Will fix and release again 馃憤

Thank you

We changed {} to be Exact<{ [key: string]: never; }>, this will make sure that no other fields are being used, and also gives a nice TS error when field isn't known.

https://github.com/dotansimha/graphql-code-generator/pull/4201

@oceandrama can you please try 1.15.3-alpha-a0eddf41.0?

@dotansimha It works well, but I think, it may have a simpler implementation without Exact type.
Everything worked as expected without Exact type

type Variables = { a: number }
let variables: Variables

variables = { a: 1 } // ok
variables = { a: 1, b: 2 } // error
variables = { } // error

you can only check {} and return never instead of variablesBlock

@oceandrama but when an operation doesn't have variables, the value could be null or undefined or {}, so just using never over the variables isn't going to cover all possible use cases of the runtime libraries.

Fixed in v1.15.3.

How long does it take to get the latest release published on NPM ?

@lewebsimple It should be available now (v1.15.3), sorry for the delay, we had a minor bug in our CI :D

Don't know if it's related to this issue, but I'm still getting TS @typescript-eslint/ban-types errors like in the following:

export type Resolver<TResult, TParent = {}, TContext = {}, TArgs = {}> =
  | ResolverFn<TResult, TParent, TContext, TArgs>
  | StitchingResolver<TResult, TParent, TContext, TArgs>;

Can I safely ignore that ?

@lewebsimple I don't thing it's related to this PR, it seems like something else.

No need to run lint rules on generates files. It's endless, because everyone prefers something else, and we can't align to all requirements :)

I recommend you to use @graphql-codegen/add plugin and do something like that:

generates:
  my-types.ts:
    plugins:
      - add: '/* eslint-disable */'
      - typescript
      - typescript-resolvers

And btw, if you are not using schema-stitching resolvers, you can turn it off by adding:

generates:
  my-types.ts:
    config:
      noSchemaStitching: true
    plugins:
      - add: '/* eslint-disable */'
      - typescript
      - typescript-resolvers
Was this page helpful?
0 / 5 - 0 ratings