typescript 在GraphQL codegen中生成正确的类型而不是union

vx6bjr1n  于 2023-06-30  发布在  TypeScript
关注(0)|答案(3)|浏览(129)

我正在尝试迁移一个设置,它生成的所有类型都与服务器所具有的类型完全相同,而这个设置只基于我们编写的文档节点。
我目前在.graphqlrc.js中有此配置

/** @type {import('graphql-config').IGraphQLConfig} */
const graphqlConfig = {
  schema: process.env.NEXT_PUBLIC_API_URL,
  documents: './src/graphql/**/*.ts',
  extensions: {
    codegen: {
      hooks: {
        afterAllFileWrite: ['prettier --write'],
      },
      generates: {
        './src/__generated__/graphql.ts': {
          plugins: [
            'typescript',
            'typescript-operations',
            {
              add: {
                content: '/* eslint-disable */',
              },
            },
          ],
          config: {
            disableDescriptions: true,
          },
        },
        './src/__generated__/introspection-result.ts': {
          plugins: ['fragment-matcher'],
          config: {
            useExplicitTyping: true,
          },
        },
      },
    },
  },
}

这就产生了如下的结果

export type QueryName = {
  __typename?: 'Query'
  resource?:
    | { __typename?: 'A' }
    | { __typename?: 'B' }
    | {
        __typename?: 'C'
        id: string
        prop1: any
        prop2: any
      }
}

这可不是我所期望的我期待的是

export type QueryName = {
  __typename?: 'Query'
  resource?: {
        __typename?: 'C'
        id: string
        prop1: any
        prop2: any
  }
}

因为我只查询C。当前生成的类型将影响很多代码,而如果我可以输出我想要实现的,我们只需要更改类型。
我试着玩配置发现here,但无法找到解决方案。请让我知道这是可能的,或者如果有什么我可以看看,以解决这个问题。
先谢谢你了!

zte4gxcn

zte4gxcn1#

我最终使用了tiny-invariant包。考虑ff代码

const {data} = useUserQuery({variables: {id}});

// more codes here...

invariant(data.user.__typename === "User");

// now we should get the type that we want here
vnjpjtjt

vnjpjtjt2#

你也可以

if (data.user.__typename === "User") { ... };

以确保它引用的是您需要的联合中的类型

xdyibdwo

xdyibdwo3#

有一个很好的解决方案!
例如,你有这样的东西:

export type GetProductQuery = {
  __typename?: 'Query'
  product?:
    | { __typename: 'NotFound'; message: string }
    | {
        __typename: 'Product'
        id: string
        title: string
        currentPrice: number
      }
    | null
}

然后,可以使用提取实用程序类型

type QueryProductData = Extract<GetProductQuery['product'], { __typename: 'Product' }>
type QueryNotFoundData = Extract<GetProductQuery['product'], { __typename: 'NotFound' }>

从这些类型中,您可以在将来构造任何类型。

相关问题