为 GraphQL API 手动编写 TypeScript 类型很容易导致类型漂移、运行时错误和浪费开发时间。类型生成完全自动化这一过程,使前端类型与 API schema 完美同步。
即时将 GraphQL schema 转换为 TypeScript 类型 →
1. 为什么类型生成很重要
GraphQL API 设计上就是强类型的——schema 定义了每个查询、变更、字段和参数。但没有类型生成,前端开发者会在 TypeScript 中手动复制这些类型,创建两个不可避免会发散的真实来源。
没有类型生成:您手动编写 TypeScript 接口,希望它们与 schema 匹配,然后在生产环境中以运行时错误的形式发现不匹配。当 API 添加字段时,您的类型已经过时。
有类型生成:类型从 schema 自动生成。当 API 更改时,重新生成类型,TypeScript 编译器会准确告诉您哪些前端代码需要更新。零猜测。
类型生成通常在中型项目上每周节省 2–5 小时,并消除了一整类 bug。
2. 手动 vs 自动方法
以下是两种方法的比较:
| 方面 | 手动 | 自动 |
|---|---|---|
| Accuracy | Error-prone | Always matches schema |
| Maintenance | Manual updates needed | One command to sync |
| Setup Cost | None | ~15 min one-time setup |
| Ongoing Cost | Hours per week | Near zero |
| Schema Drift Detection | At runtime (production) | At compile time (CI) |
手动类型的唯一合理原因是当您使用的是一个小型、很少变化的 API 且不想添加工具。其他情况都应自动化。
3. GraphQL SDL 基础
Schema 定义语言(SDL)是编写 GraphQL schema 的方式。理解 SDL 对于使用类型生成器至关重要:
type User {
id: ID!
name: String!
email: String!
age: Int
posts: [Post!]!
role: Role!
}
type Post {
id: ID!
title: String!
content: String
author: User!
tags: [String!]
createdAt: DateTime!
}
enum Role {
ADMIN
EDITOR
VIEWER
}
input CreateUserInput {
name: String!
email: String!
age: Int
role: Role = VIEWER
}SDL 支持这些关键构造:type(对象类型)、input(输入对象)、enum(枚举类型)、interface(抽象类型)、union(联合类型)和 scalar(自定义标量类型)。
感叹号(!)表示非空。没有它,字段默认为可空——这与大多数编程语言相反。
4. 类型映射规则
类型生成器遵循一致的规则将 GraphQL 类型映射到 TypeScript:
| GraphQL | TypeScript | 备注 |
|---|---|---|
String! | string | Non-nullable string |
String | string | null | Nullable string |
Int! / Float! | number | JS has one number type |
Boolean! | boolean | Direct mapping |
ID! | string | IDs are serialized as strings |
[String!]! | string[] | Non-null array of non-null strings |
[String] | (string | null)[] | null | Nullable array of nullable strings |
enum Role | enum Role | TS enum or string union |
理解这些映射有助于预测和验证生成输出,并编写能产生更干净 TypeScript 类型的 GraphQL schema。
5. 代码生成器
几个工具可以从 GraphQL schema 生成 TypeScript 类型。最流行的:
GraphQL Code Generator(@graphql-codegen)是行业标准。它基于插件,不仅支持类型,还支持为 React Query、Apollo 和 urql 生成类型化的 hooks:
# codegen.ts
import type { CodegenConfig } from '@graphql-codegen/cli';
const config: CodegenConfig = {
schema: './schema.graphql', // or a URL
documents: 'src/**/*.graphql', // your queries/mutations
generates: {
'src/generated/graphql.ts': {
plugins: [
'typescript',
'typescript-operations',
'typescript-react-query', // optional: typed hooks
],
},
},
};
export default config;替代生成器:
- gql.tada — 无需代码生成的编译时类型推断,使用 TypeScript 模板字面量类型
- Pothos — 代码优先的 schema 构建器,从解析器代码派生类型
- genql — 从任何 GraphQL 端点生成完全类型化的 SDK 客户端
6. 集成工作流
典型的类型生成工作流集成到您的开发和 CI/CD 管道中:
- 开发:在开发服务器旁以监视模式(
--watch)运行 codegen。编辑.graphql文件时类型自动更新 - 预提交:将 codegen 添加到预提交钩子,确保生成的类型始终被提交
- CI/CD:在 CI 中运行 codegen 和
tsc --noEmit,在部署前捕获 schema 漂移 - Schema 更新:当后端更新 schema 时,重新生成类型并修复任何 TypeScript 错误后再合并
推荐的 package.json 脚本:
{
"scripts": {
"codegen": "graphql-codegen",
"codegen:watch": "graphql-codegen --watch",
"typecheck": "tsc --noEmit",
"precommit": "npm run codegen && npm run typecheck"
}
}将生成的文件纳入版本控制。这让 PR 清晰展示 schema 变更的影响,并让开发者无需本地运行 codegen 即可工作。
7. 工具推荐:GraphQL 转 TypeScript
需要快速将 GraphQL schema 转换为 TypeScript 类型,无需设置完整的 codegen 管道?我们的 GraphQL 转 TypeScript 转换器几秒即可处理:
- 将 GraphQL 对象类型转换为 TypeScript 接口
- 正确映射枚举、输入类型和联合类型
- 处理可空与非空字段
- 支持嵌套和递归类型定义
粘贴 GraphQL SDL,即时获取干净的 TypeScript 类型。非常适合快速原型设计、学习和一次性转换。
即时将 GraphQL schema 转换为 TypeScript 类型 →
常见问题
应该使用代码生成还是 gql.tada 来实现类型安全?
对于大多数团队,GraphQL Code Generator 是更安全的选择——它拥有更广泛的生态系统支持,适用于任何客户端库,并生成标准 TypeScript 文件。gql.tada 很创新,但需要 TypeScript 5.0+ 且学习曲线更陡。如果您想要零配置的类型安全且团队熟悉高级 TypeScript,可以选择 gql.tada。
应该多久重新生成一次类型?
开发时使用监视模式即时重新生成。在 CI 中每次推送时运行 codegen。关键规则:永远不要手动编辑生成的文件。如果需要自定义类型,创建一个单独的文件来导入和扩展生成的类型。
可以从远程 GraphQL 端点生成类型吗?
可以。大多数代码生成器支持内省——它们可以查询运行中的 GraphQL 服务器获取 schema 并从中生成类型。在 codegen 配置中配置端点 URL 即可。对于生产 API,您也可以将 schema 导出为 SDL 文件并以此为源。