简体   繁体   English

Typescript & Gatsby: gatsby-plugin-ts + graphQL 查询集成

[英]Typescript & Gatsby: gatsby-plugin-ts + graphQL queries integration

I'm using gatsby-plugin-ts to generate types for my graphql page queries.我正在使用gatsby-plugin-ts为我的 graphql 页面查询生成类型。

The issue I have is that all types generated return a T | undefined我遇到的问题是生成的所有类型都返回T | undefined 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.所有字段的T | undefined类型,所以我需要在任何组件中使用它们之前检查所有查询子字段,否则编译器会抛出错误。

Take gatsby-plugin-image for example.gatsby-plugin-image为例。 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结果data.banner应传递给getImage function,但如果您尝试这样做,typescript 可以理解地抛出以下错误,因为 undefined 不能分配给getImage预期的IGAtsbyImageData 打字稿错误

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.当涉及到更复杂的查询时,情况就更糟了,比如来自 markdownremark 插件的查询:每次都需要手动检查一个查询结果的所有子字段。 Is there a work around for this?有解决办法吗?

type of data.banner should be ImageDataLike data.banner 的类型应该是 ImageDataLike

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

This appears to be caused by a bug in the gatsby-plugin-image typings.这似乎是由gatsby-plugin-image中的错误引起的。 Unfortunately the typings for getImage , getSrc , etc. don't match their null-safe behaviour .不幸的是getImagegetSrc等的类型与它们的 null-safe 行为不匹配 This also looks like it was only partially fixed, since the troublesome | null这看起来也只是部分修复,因为麻烦| null | null type is down one level on { childImageSharp: { gatsbyImageData: IGatsbyImageData } | null } | null类型在{ childImageSharp: { gatsbyImageData: IGatsbyImageData } | null }上下降了一级{ childImageSharp: { gatsbyImageData: IGatsbyImageData } | null } (at least in the GraphQL Typegen typings - YMMV). { childImageSharp: { gatsbyImageData: IGatsbyImageData } | null } (至少在 GraphQL Typegen 分型 - 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 ".这告诉 Typescript:“嘿,我知道这些类型不完全匹配,但相信我data.banner将永远是ImageDataLike ”。


Of course, you can avoid all this if you're happy to define your typings manually, as in @Alexey's answer.当然,如果您愿意手动定义您的类型,您可以避免所有这些,就像@Alexey 的回答一样。

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.如果你想坚持使用自动生成的类型,我建议升级到 Gatsby 内置并保持最新的官方GraphQL Typegen

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM