Typescript & Gatsby: gatsby-plugin-ts + graphQL queries integration
Asked Answered
G

2

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?

Goldman answered 20/3, 2021 at 11:33 Comment(4)
You should switch over to github.com/cometkim/gatsby-plugin-typegen, which does the same thing but much better maintained.Driver
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?Cagle
@DerekNguyen Gatsby now includes a built-in GraphQL Typegen feature, all you need to do is turn on a config setting. gatsbyjs.com/docs/how-to/local-development/graphql-typegenExpecting
@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.Expecting
E
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.

Expecting answered 3/9, 2022 at 16:18 Comment(0)
Q
1

type of data.banner should be ImageDataLike

export interface DataBannerProps {
  banner: ImageDataLike;
  alt: string;
}
Quijano answered 16/5, 2022 at 12:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.