跳到主要内容

类型安全:GraphQL To TypeScript定义 — Numio

使用 @graphql-codegen/typescript 根据 GraphQL schema 生成 TypeScript 类型,并为 Document 面板中的操作生成结果类型和变量类型。可空字段变为可选的 Maybe<T> 属性;非空列表变为 Array<T>。

在前端为查询返回的数据添加类型,无需配置 codegen.yml 和运行 CLI。

GraphQL Schema

Document

TypeScript

适用场景

  • 在前端为查询返回的数据添加类型,无需配置 codegen.yml 和运行 CLI。
  • 在提交前查看 schema 变更(字段变为可空、新增枚举值)在生成的 TypeScript 中是什么样子。

使用方法

  1. 将 SDL(type、enum、interface、union、scalar 定义)粘贴到 GraphQL Schema 编辑器。
  2. 将 query、mutation 或 fragment 放入 Document 编辑器,或将其清空以只获取 schema 类型;与 schema 不匹配的 document 会被跳过,并输出一条警告注释。
  3. 复制生成的类型:User 等 schema 类型,以及每个具名操作对应的 GetUserQuery 和 GetUserQueryVariables。

GraphQL schema + document

# GraphQL Schema editor
type Query {
  user(id: ID!): User
}

type User {
  id: ID!
  name: String
  tags: [String!]!
}

# Document editor
query GetUser($id: ID!) {
  user(id: $id) { id name }
}

TypeScript 类型

…
export type Query = {
  __typename?: "Query"
  user?: Maybe<User>
}

export type QueryUserArgs = {
  id: Scalars["ID"]["input"]
}

export type User = {
  __typename?: "User"
  id: Scalars["ID"]["output"]
  name?: Maybe<Scalars["String"]["output"]>
  tags: Array<Scalars["String"]["output"]>
}

export type GetUserQueryVariables = Exact<{
  id: Scalars["ID"]["input"]
}>

export type GetUserQuery = {
  __typename?: "Query"
  user?: { __typename?: "User"; id: string; name?: string | null } | null
}

功能与限制

输出开头是固定的辅助类型(Maybe、InputMaybe、Exact、MakeOptional、Scalars 等),上例中缩写为 '…'。Scalars 为每个标量分别映射 input 和 output 类型。

Date 等自定义标量的类型为 any;枚举值变为键名为 PascalCase 的 TypeScript enum(USER 变为 User = "USER")。

生成在浏览器的 Web Worker 中运行,不会上传任何内容。结果用 Prettier 格式化且不带分号,页面没有 codegen 配置选项。

FAQ

为什么输出以 "// Document ignored" 开头?

Document 编辑器的内容会按你的 schema 校验,而默认示例查询了 username 等字段。校验失败时,页面仍会生成 schema 类型,并将第一条错误以注释形式放在顶部。请修正操作或清空 Document 编辑器。

可空字段如何类型化?

像 name: String 这样的可空字段会变为 name?: Maybe<Scalars["String"]["output"]>,其中 Maybe<T> 即 T | null。在操作结果类型中则内联写作 name?: string | null。

查询类型中是否只包含选中的字段?

是。GetUserQuery 只包含查询选中的字段(这里是 id 和 name),__typename 为可选属性;完整的 User 类型会单独生成。

规范与参考资料