How to narrow Typescript Types autogenerated by graphQL codegen?
Asked Answered
T

2

7

I get a TypeScript type autogenerated from AWS-Amplify GraphQL (which uses apollo-codegen I believe) like such:

export type GetNoteQuery = {
  getNote:  {
    __typename: "Note",
    id: string,
    createdAt: string | null,
    updatedAt: string | null,
    title: boolean | null,
    content: string | null,
  } | null,

I want to generate a base type of "Note" to use as "base" type to use in my code when using the returned data. I.e. mapping notes onto a React component, etc.

Is there a way to narrow this type that is auto generated, or to extend it in some way, to have it look like:

type Note = {
    id: string,
    createdAt: string | null,
    updatedAt: string | null,
    title: boolean | null,
    content: string | null
}

Taoism answered 3/11, 2019 at 18:24 Comment(0)
B
2

You can use an index query to get the type of getNote coupled with Exclude to get rid of the the null from the property type. You then can use Omit to get rid of the extra property.

export type GetNoteQuery = {
  getNote: {
    __typename: "Note",
    id: string,
    createdAt: string | null,
    updatedAt: string | null,
    title: boolean | null,
    content: string | null,
  } | null
}

type Note = Omit<Exclude<GetNoteQuery['getNote'], null>, '__typename'>

You can also use an interface to get a stronger name for the type:


interface Note extends Omit<Exclude<GetNoteQuery['getNote'], null>, '__typename'> { }


Bankston answered 3/11, 2019 at 19:55 Comment(2)
Thank you! What do you mean by using an interface to "get a stronger name for the type"?Taoism
@StephenA.Lizcano type aliases get expanded in errors and tooltips, so you might see something like Pick<Exclude<.... instead of Note. Interface names are always preserved.Bankston
P
2

GraphQL-Codegen creator here.

Just some background on the decision to generate this kind of TS code: We started typescript as a plugin for creating an exact representation of the GraphQL schema. Then, typescript-operations take operations and fragments (that picks specific fields and data from the schema) and generates code that takes the same fields and data fields from the generated types by typescript plugin.

We saw some developers prefer cleaner code, so you can use preResolveTypes: true to avoid using Pick and just use the primitive type in-place. You can also use onlyOperationTypes: true in order to tell the codegen to avoid generating types that are not needed.

Ptolemaic answered 20/7, 2021 at 14:19 Comment(1)
Appreciate your answer @dotan! Will definitely try asap and provide feedback, seems really usable for us.Spevek

© 2022 - 2024 — McMap. All rights reserved.