如何按Kind限制graphql-codegen生成类型并解决命名冲突?
GraphQL Codegen 类型生成优化方案
问题背景
我用graphql-codegen给内部包生成类型,只需要对接大型应用Schema里的极小子集做Graph查询。但拼接后的Schema里有同名但Kind分别是INPUT_OBJECT和OBJECT的对象,导致生成的TypeScript代码因为命名重复直接无效。
我想实现两个目标:要么按特定Kind过滤生成的类型,要么只生成我指定的查询/变更/订阅文档对应的类型,把生成代码从几千行砍到一百多行。现在省略typescript插件能接近目标,但会缺失Exact、Scalars和响应类型定义。暂时只能把overwrite设为false手动补缺失的类型,但这种方式没法和应用的变更同步,想找更好的办法。
当前配置:
overwrite: false schema: "http://localhost:3000/graph" documents: ["src/graphql/QueryOne.graphql", "src/graphql/QueryTwo.graphql", "src/graphql/QueryThree.graphql"] config: withHooks: true reactApolloVersion: 3 generates: "./src/lib/graphql.tsx": plugins: - "typescript-operations" - "typescript-react-apollo"
优化方案
1. 启用typescript插件的onlyOperationTypes配置
把typescript插件加回来,同时开启onlyOperationTypes: true,这样只会生成和你指定的查询文档关联的类型,不会把整个Schema的所有类型都生成出来——既能保留Exact、Scalars这些基础类型,又能大幅缩减代码量。
2. 自定义命名规则解决同名冲突
针对INPUT_OBJECT和OBJECT同名的问题,用namingConvention配置给INPUT_OBJECT类型加后缀(比如${name}Input),彻底避免命名重复报错。
3. 可选精简配置(按需添加)
skipTypename: true:如果你的查询不需要__typename字段,可以去掉相关类型生成enumsAsTypes: true:把枚举生成为TypeScript类型而非枚举,进一步精简代码
修改后的配置示例
overwrite: true # 改回true自动同步变更,不用手动维护 schema: "http://localhost:3000/graph" documents: ["src/graphql/QueryOne.graphql", "src/graphql/QueryTwo.graphql", "src/graphql/QueryThree.graphql"] config: withHooks: true reactApolloVersion: 3 # 只生成和操作关联的类型 onlyOperationTypes: true # 给INPUT_OBJECT类型加Input后缀,避免同名冲突 namingConvention: typeNames: keep enumValues: keep transformUnderscore: false inputTypes: "${name}Input" # 可选:跳过__typename字段生成 skipTypename: true generates: "./src/lib/graphql.tsx": plugins: - "typescript" # 加回来获取基础类型 - "typescript-operations" - "typescript-react-apollo"
效果说明
- 生成的代码只会包含你实际用到的查询/变更对应的类型,代码量会大幅缩减到预期的百余行
- 自动处理INPUT_OBJECT和OBJECT的同名冲突,不会出现命名重复报错
- 保留Exact、Scalars等必要基础类型,不需要手动补充
- overwrite设为true后,能自动和应用的Schema变更同步,不用手动维护
内容的提问来源于stack exchange,提问作者pwdst
相关产品推荐
相关产品推荐

