本文へスキップ

GraphQLからTypeScript定義への変換 — Numio

@graphql-codegen/typescript で GraphQL スキーマから TypeScript の型を生成し、Document パネルにあるオペレーションの結果型と変数型も出力します。nullable なフィールドは省略可能な Maybe<T> プロパティに、non-null のリストは Array<T> になります。

codegen.yml の設定や CLI の実行なしに、フロントエンドでクエリが返すデータに型を付ける。

GraphQL Schema

Document

TypeScript

こんなときに使えます

  • codegen.yml の設定や CLI の実行なしに、フロントエンドでクエリが返すデータに型を付ける。
  • スキーマの変更(フィールドが nullable になる、enum 値が増える)が生成される TypeScript でどう見えるかを、コミット前に確認する。

使い方

  1. SDL(type、enum、interface、union、scalar の定義)を GraphQL Schema エディターに貼り付けます。
  2. query、mutation、fragment を Document エディターに入れるか、スキーマの型だけが欲しければ空にします。スキーマと合わないドキュメントは警告コメント付きでスキップされます。
  3. 生成された型をコピーします:User などのスキーマ型と、名前付きオペレーションごとの GetUserQuery と GetUserQueryVariables。

GraphQL スキーマ + ドキュメント

# 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 は各スカラーを入力用と出力用の型に分けて対応付けます。

Date などのカスタムスカラーは any 型になります。enum 値は PascalCase のキーを持つ TypeScript の enum になります(USER は User = "USER")。

生成はブラウザの Web Worker で実行され、何もアップロードされません。結果はセミコロンなしで Prettier 整形され、ページに codegen の設定オプションはありません。

FAQ

出力が "// Document ignored" で始まるのはなぜですか?

Document エディターの内容はスキーマに対して検証されます。デフォルトの例は username などのフィールドをクエリしています。検証に失敗してもスキーマの型は生成され、最初のエラーが先頭にコメントとして入ります。オペレーションを修正するか、Document エディターを空にしてください。

nullable なフィールドはどう型付けされますか?

name: String のような nullable フィールドは name?: Maybe<Scalars["String"]["output"]> になります。Maybe<T> は T | null です。オペレーションの結果型では name?: string | null とインラインで書かれます。

クエリの型には選択したフィールドだけが含まれますか?

はい。GetUserQuery にはクエリが選択したフィールド(ここでは id と name)だけが入り、__typename は省略可能なプロパティになります。完全な User 型は別に生成されます。

仕様を確認する