6

I'm using gatsby-plugin-ts to generate types for my graphql page queries.

The issue I have is that all types generated return a T | undefined type for all fields, so I would need to check all query subfields before using them in any component, otherwise the compiler will throw an error.

Take gatsby-plugin-image for example. Given a query:

export const query = graphql`
  query IndexPage {
    banner: file(relativePath: { eq: "banner.jpg" }) {
      childImageSharp {
        gatsbyImageData(width: 1920)
      }
    }
  }
`;

The result data.banner should be passed to the getImage function, though if you try to do so typescript understandably throws the following error, since undefined is not assignable to IGAtsbyImageData expected by getImage typescript error

And this is even worse when it comes to more complex queries, like the ones from the markdownremark plugin: all subfields of one query result would need to be manually checked every time. Is there a work around for this?

barmanthewise
  • 359
  • 4
  • 10
  • 2
    You should switch over to https://github.com/cometkim/gatsby-plugin-typegen, which does the same thing but much better maintained. – Derek Nguyen Mar 20 '21 at 14:11
  • I expected this to work outside of the box. I have the same problem, and don't want to use `gatsby-plugin-typegen` just for this. Did you find a solution? – Daniel May 19 '21 at 08:50
  • @DerekNguyen Gatsby now includes a built-in GraphQL Typegen feature, all you need to do is turn on a config setting. https://www.gatsbyjs.com/docs/how-to/local-development/graphql-typegen/ – Samuel Jaeschke Sep 03 '22 at 15:51
  • @dspacejs If you don't want to use a plugin to automatically generate your typings then you can just write them manually as in Alexey Chekmarev's answer. – Samuel Jaeschke Sep 03 '22 at 15:54

2 Answers2

2

This appears to be caused by a bug in the gatsby-plugin-image typings. Unfortunately the typings for getImage, getSrc, etc. don't match their null-safe behaviour. This also looks like it was only partially fixed, since the troublesome | null type is down one level on { childImageSharp: { gatsbyImageData: IGatsbyImageData } | null } (at least in the GraphQL Typegen typings - YMMV).

The easiest workaround is to use a type assertion:

const result = getImage(data.banner as ImageDataLike);

This tells Typescript: "Hey, I know these types don't exactly match, but trust me, data.banner will always be an ImageDataLike".


Of course, you can avoid all this if you're happy to define your typings manually, as in @Alexey's answer.

If you want to stick with auto-generated types, I'd recommend upgrading to the official GraphQL Typegen which is built into Gatsby and kept up-to-date.

Samuel Jaeschke
  • 1,126
  • 11
  • 23
1

type of data.banner should be ImageDataLike

export interface DataBannerProps {
  banner: ImageDataLike;
  alt: string;
}