graphql-code-generator icon indicating copy to clipboard operation
graphql-code-generator copied to clipboard

`InputMaybe` should explicitly include `undefined`

Open ericbf opened this issue 1 year ago • 6 comments

Which packages are impacted by your issue?

@graphql-codegen/add @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-operations

Describe the bug

When using the typescript compiler option "exactOptionalPropertyTypes": true, the fact that InputMaybe<T> does not explicitly include undefined makes it hard to use as you can no longer pass optional values to query variables.

InputMaybe should explicitly include undefined to allow passing optional values to optional variables in queries.

Your Example Website or App

https://stackblitz.com/edit/github-txjvxl?file=query.ts

Steps to Reproduce the Bug or Issue

  1. Open repro
  2. Look at compilation error (if it doesn't show in the editor, run npx tsc to see it)

Expected behavior

No compilation error. Since input variable id is optional, it should allow an optional value to be set to it.

Screenshots or Videos

No response

Platform

  • OS: macOS
  • NodeJS: 18.20.3
  • graphql version: ^16.2.0
  • @graphql-codegen/add version: ^5.0.0
  • @graphql-codegen/cli version: ^4.0.1
  • @graphql-codegen/typescript version: ^4.0.1
  • @graphql-codegen/typescript-operations version: ^4.0.1

Codegen Config File

import { CodegenConfig } from "@graphql-codegen/cli";

const config: CodegenConfig = {
  schema: "schema.graphql",
  documents: "document.graphql",
  generates: {
    "types.ts": { plugins: ["typescript", "typescript-operations"] },
  },
};

export default config;

Additional context

There’s an option to customize the InputMaybe type, but when using some presents, like the client preset, the option is not available. I feel codegen should work in a way compatible with at least this relatively non-niche typescript config.

ericbf avatar Jun 14 '24 15:06 ericbf

Hi @ericbf

inputMaybeValue can be used to add undefined like this:

const config: CodegenConfig = {
  // ...
  generates: {
    'path/to/file.ts': {
      plugins: ['typescript'],
      config: {
        inputMaybeValue: 'T | null | undefined' // Add undefined to inputMaybeValue
      }
    }
  }
}

eddeee888 avatar Jul 01 '24 10:07 eddeee888

I'll close this issue, but if this doesn't answer your question, please @ me and let me know to re-open 🙂

eddeee888 avatar Jul 01 '24 10:07 eddeee888

@eddeee888 I should have specified I’m using the client preset, and this option doesn’t work when using the client preset. I’ve updated the issue description accordingly.

ericbf avatar Jul 01 '24 12:07 ericbf

We are having the same Problem. Being able to set inputMaybeValue with the client preset would solve the problem for us.

DB-Vadim-Wagner avatar Aug 23 '24 12:08 DB-Vadim-Wagner

I'm using the client preset. I'm getting these errors when using exactOptionalPropertyTypes: true:

$ npx tsc --noEmit
src/graphql/generated/fragment-masking.ts:74:22 - error TS2344: Type 'TypedDocumentString<Incremental<TFrag>, any>' does not satisfy the constraint 'DocumentTypeDecoration<any, any>'.
  Types of property '__apiType' are incompatible.
    Type '((variables: any) => Incremental<TFrag>) | undefined' is not assignable to type '(variables: any) => any'.
      Type 'undefined' is not assignable to type '(variables: any) => any'.

74   data: FragmentType<TypedDocumentString<Incremental<TFrag>, any>> | null | undefined
                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

src/graphql/generated/fragment-masking.ts:75:25 - error TS2344: Type 'TypedDocumentString<TFrag, any>' does not satisfy the constraint 'DocumentTypeDecoration<any, any>'.
  Types of property '__apiType' are incompatible.
    Type '((variables: any) => TFrag) | undefined' is not assignable to type '(variables: any) => any'.
      Type 'undefined' is not assignable to type '(variables: any) => any'.

75 ): data is FragmentType<typeof fragmentNode> {
                           ~~~~~~~~~~~~~~~~~~~

src/graphql/generated/graphql.ts:2066:14 - error TS2420: Class 'TypedDocumentString<TResult, TVariables>' incorrectly implements interface 'DocumentTypeDecoration<TResult, TVariables>'.
  Types of property '__apiType' are incompatible.
    Type '((variables: TVariables) => TResult) | undefined' is not assignable to type '(variables: TVariables) => TResult'.
      Type 'undefined' is not assignable to type '(variables: TVariables) => TResult'.

2066 export class TypedDocumentString<TResult, TVariables>
                  ~~~~~~~~~~~~~~~~~~~


Found 3 errors in 2 files.

Errors  Files
     2  src/graphql/generated/fragment-masking.ts:74
     1  src/graphql/generated/graphql.ts:2066

nelson6e65 avatar Jan 16 '25 04:01 nelson6e65

Hi @nelson6e65 ,exactOptionalPropertyTypes issue is tracked here

eddeee888 avatar Jan 21 '25 10:01 eddeee888

Hello, is there a reason why inputValueMaybe is not available in the client preset?

ubermanu avatar Jul 29 '25 07:07 ubermanu

Hi all,

inputValueMaybe will not be forwarded, but will be set as T | null | undefined by default. This is because Client Preset is supposed to manage the sensible defaults so users don't have to do it themselves.

For client use cases, I believe the only option for inputValueMaybe is T | null | undefined. If this is not the case, please let me know! 🙂

eddeee888 avatar Aug 03 '25 13:08 eddeee888

Hello 👋

@graphql-codegen/client-preset@4.8.4-alpha-20250806124710-efb35af844f5324e3d57c71e731b0b927866b260 is released with the default inputValueMaybe being T | null | undefined.

Please test it out and let me know whether it works! 🙏

eddeee888 avatar Aug 14 '25 12:08 eddeee888

Even though I'm not the creator of this issue, I can confirm this fixes the problem related to exact optional types.

ssternal avatar Sep 11 '25 08:09 ssternal

This is fixed and released: https://github.com/dotansimha/graphql-code-generator/releases/tag/release-1757946883958

eddeee888 avatar Sep 15 '25 14:09 eddeee888