Graphql-code-generator: [TypeScript Compatibility] Should work with strict mode

Created on 9 Apr 2019  路  11Comments  路  Source: dotansimha/graphql-code-generator

Without strict mode:
image

With strict mode:
image

I think we need to add support for it, by wrapping the proxy type with NonNullable:

export type Users = NonNullable<NonNullable<GetAccountUsersQuery['account']>['users']>[0];
bug plugins waiting-for-release

Most helpful comment

Fixed in 1.1.0 馃殌

All 11 comments

We are trying to upgrade to v1 to solve some other issue, so we started using the compatibility layer to help on the migrations and we hit this as well. We definably want to keep strict mode enabled. Any help on this would be highly appreciated.

@josemarluedke I'm working on fixing that.
Did you had other issues with the rest of the plugins?

I think I'm hitting another variant of this, accessing a field on a record in an array:

# schema
type Mutation {
  employeeCreateWidgets(data: EmployeeCreateWidgetArgs!): [Widget]
}
# mutation
mutation EmployeeCreateWidgets($data: EmployeeCreateWidgetArgs!) {
  employeeCreateWidgets(data: $data) {
    employee {
      id
      name
      }
    }
  }
// generated code
export namespace EmployeeCreateWidgets {
  export type Variables = EmployeeCreateWidgetsMutationVariables;
  export type Mutation = EmployeeCreateWidgetsMutation;
  export type EmployeeCreateWidgets = (NonNullable<
    EmployeeCreateWidgetsMutation["employeeCreateWidgets"]
  >)[0];
  export type Employee = (NonNullable<
    EmployeeCreateWidgetsMutation["employeeCreateWidgets"]
  >)[0]["employee"];
}

That final array access (_"employee"_) is squiggled, with the following error:

Property 'employee' does not exist on type 'Maybe<{ __typename?: "Widget" | undefined; } & { employee: { __typename?: "Employee" | undefined; } & Pick; }>'.ts(2339)

Using canary typescript-compatibility, which is currently:

jrr@jrrmbp ~/d/2019.04.11-gql-codegen-issue (master)>
grep version node_modules/@graphql-codegen/typescript-compatibility/package.json
  "version": "1.0.8-alpha-b387ab83.16+b387ab83",

Here's a runnable repro (yarn run gql-gen):
https://github.com/jrr/gql-codegen-issue

Fixed in 1.1.0 馃殌

Hi,

I just tried with 1.1.0 but I'm still facing this issue:

image

//package.json
{
    "@graphql-codegen/add": "1.1.0",
    "@graphql-codegen/cli": "1.1.0",
    "@graphql-codegen/typescript": "1.1.0",
    "@graphql-codegen/typescript-compatibility": "1.1.0",
    "@graphql-codegen/typescript-operations": "1.1.0"
}
// tsconfig.json
{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "baseUrl": "./",
    "esModuleInterop": true,
    "jsx": "react",
    "lib": ["es5", "es2015", "es2016", "dom"],
    "module": "es6",
    "moduleResolution": "node",
    "noImplicitAny": true,
    "noUnusedParameters": true,
    "outDir": "./dist/",
    "paths": {
      "~/*": ["src/*"]
    },
    "sourceMap": true,
    "strict": true,
    "target": "es5",
    "pretty": true,
    "typeRoots": ["./typings", "./node_modules/@types"],
    "skipLibCheck": true
  },
  "include": ["./src/**/*"],
  "exclude":  ["dist", "node_modules"]
}
#codegen.yml
overwrite: true
schema: "./src/graphql/__generated__/schema.json"
documents: "./src/graphql/**/*.ts"
config:
  noNamespaces: true
  maybeValue: T | undefined | null
generates:
  src/graphql/__generated__/types.ts:
    plugins:
      - add: "/* tslint:disable */"
      - add: "// THIS IS A GENERATED FILE, DO NOT EDIT IT!"
      - "typescript"
      - "typescript-compatibility"
      - "typescript-operations"

// generated code


export type GetApplicationsQuery = {__typename?: 'Query'} & {
  applicationsForJob: Maybe<
    {__typename?: 'Applications'} & Pick<Applications, 'total'> & {
        applications: Array<
          Maybe<
            {__typename?: 'Application'} & Pick<Application, 'createdOn' | 'id' | 'isViewed'> & {
                job: {__typename?: 'Job'} & Pick<Job, 'uuid'>;
                applicant: {__typename?: 'Candidate'} & Pick<Candidate, 'email' | 'name' | 'id' | 'mobileNumber'> & {
                    education: Array<
                      Maybe<
                        {__typename?: 'Education'} & Pick<
                          Education,
                          | 'name'
                          | 'isHighest'
                          | 'institution'
                          | 'yearAttained'
                          | 'ssecEqaDescription'
                          | 'ssecFosDescription'
                        >
                      >
                    >;
                    skills: Array<Maybe<{__typename?: 'Skill'} & Pick<Skill, 'id' | 'skill'>>>;
                    workExperiences: Array<
                      Maybe<
                        {__typename?: 'WorkExperience'} & Pick<
                          WorkExperience,
                          'jobTitle' | 'companyName' | 'startDate' | 'endDate' | 'jobDescription'
                        >
                      >
                    >;
                    resume: Maybe<{__typename?: 'Resume'} & Pick<Resume, 'fileName' | 'filePath' | 'lastDownloadedAt'>>;
                  };
                scores: {__typename?: 'ApplicationScore'} & Pick<ApplicationScore, 'wcc' | 'jobkred'>;
              }
          >
        >;
      }
  >;
};

export type GetApplicationsVariables = GetApplicationsQueryVariables;
export type GetApplicationsApplicationsForJob = GetApplicationsQuery['applicationsForJob'];
export type GetApplicationsApplications = GetApplicationsQuery['applicationsForJob']['applications'][0];
export type GetApplicationsJob = GetApplicationsQuery['applicationsForJob']['applications'][0]['job'];
export type GetApplicationsApplicant = GetApplicationsQuery['applicationsForJob']['applications'][0]['applicant'];
export type GetApplicationsEducation = GetApplicationsQuery['applicationsForJob']['applications'][0]['applicant']['education'][0];
export type GetApplicationsSkills = GetApplicationsQuery['applicationsForJob']['applications'][0]['applicant']['skills'][0];
export type GetApplicationsWorkExperiences = GetApplicationsQuery['applicationsForJob']['applications'][0]['applicant']['workExperiences'][0];
export type GetApplicationsResume = GetApplicationsQuery['applicationsForJob']['applications'][0]['applicant']['resume'];
export type GetApplicationsScores = GetApplicationsQuery['applicationsForJob']['applications'][0]['scores'];

Am I missing something ? Do you need more information?

@Nebulis

You need to add strict: true to your config :)

If it still happens, can you please open a new issue with a complete example? (schema and operations)
Thanks!

It's in there. From my understanding, the problem is that some types are nullable (Maybe)

//v0.8 generation
export type GetApplicationsQuery = {
  __typename?: 'Query';

  applicationsForJob: Maybe<GetApplicationsApplicationsForJob>;
};

export type GetApplicationsApplicationsForJob = {
  __typename?: 'Applications';

  applications: (Maybe<GetApplicationsApplications>)[];

  total: number;
};
//v1.1 generation
export type GetApplicationsQuery = {__typename?: 'Query'} & {
  applicationsForJob: Maybe<
    {__typename?: 'Applications'} & Pick<Applications, 'total'> & {
        applications: ....
      }
  >;
};
export type GetApplicationsVariables = GetApplicationsQueryVariables;
export type GetApplicationsApplicationsForJob = GetApplicationsQuery['applicationsForJob'];
export type GetApplicationsApplications = GetApplicationsQuery['applicationsForJob']['applications'][0]; // this one got issue with ['applications']

If I remove Maybe then it's working well

@Nebulis I mean to the codegen config as well, because the codegen can't tell if you are using strict: true in your tsconfig. It should be:

#codegen.yml
overwrite: true
schema: "./src/graphql/__generated__/schema.json"
documents: "./src/graphql/**/*.ts"
config:
  noNamespaces: true
  strict: true
  maybeValue: T | undefined | null
generates:
  src/graphql/__generated__/types.ts:
    plugins:
      - add: "/* tslint:disable */"
      - add: "// THIS IS A GENERATED FILE, DO NOT EDIT IT!"
      - "typescript"
      - "typescript-compatibility"
      - "typescript-operations"

Great it works :)

Thanks for helping (and sorry)

Do you think it would make sense to read tsconfig configuration to perform this automatically ?

@Nebulis It might be nice, but can complicate things, because in some cases you don't want to run the codegen in the same directory as the project (for example, a monorepo with client & server - you can run the codegen from the root).

Was this page helpful?
0 / 5 - 0 ratings