cometkim / gatsby-plugin-typegen

Let's give developers using GatsbyJS better DX with extreme type-safety
https://www.gatsbyjs.org/packages/gatsby-plugin-typegen/
MIT License
204 stars 23 forks source link

Why define Maybe as T | undefined? #136

Closed nabati closed 3 years ago

nabati commented 3 years ago

Maybe this is a misunderstanding on my end, but it would be good to clarify.

In codegen.ts we define

  maybeValue: 'T | undefined',

Which gives us

type Maybe<T> = T | undefined;

If we then have a query

query DesignerPage($id: String) {
  designer(id: { eq: $id }) {
    slug
    name
  }
}

we will get the generated type.

type DesignerPageQuery = { readonly designer: Maybe<(
    Pick<Designer, 'slug' | 'name'>
  )> };

AFAICS, this type does not match the data that we are getting from the GraphQL-layer though; if no match for the id is found, the field designer will be null and not undefined.

I'm wondering why this choice was made?

cometkim commented 3 years ago

Hey @nabati, this is a very good question. It's blurry as I decided this early in the project, but I have a few answers for this.

As you said, Maybe<T> = T | undefined is not the accurate description of the data being queried. However, I think it may be more useful.

First, many React projects (include the official gatsby starters) use optional props. If a project fully adapted to GraphQL, I recommend to use fragments, but even if it isn't, I wanted the initial migration to be easier.

Second is, this plugin actually also generates types for "implicitly injected data" such as pageContext.

import * as React from 'react';
import type { PageProps } from 'gatsby';

type IndexPageProps = PageProps<GatsbyTypes.IndexPageQuery, GatsbyTypes.SitePageContext>;

and in this case, the undefined is more accurate typing for the actual pageContext value.

cometkim commented 3 years ago

The only case where this decision can be a problem is when I do the comparison null/undefined without casting, but it had not happened with most of my projects.

And I don't wanna expose the codegen configuration layer to users as much as possible.

cometkim commented 3 years ago

Closing this. But please feel free to reopen If you have any other ideas and happy new year!