本文へスキップ

GraphQLからFlow型への変換 — Numio

@graphql-codegen/flow と flow-operations を使って、GraphQL スキーマとオペレーションから Flow の型定義を生成します。オブジェクト型は exact な Flow オブジェクト({| |})に、nullable なフィールドは省略可能な maybe 型(?T)になります。

TypeScript ではなく Flow で型チェックしているコードベースに、型付きの GraphQL 結果を追加する。

GraphQL Schema

Document

Flow

こんなときに使えます

  • TypeScript ではなく Flow で型チェックしているコードベースに、型付きの GraphQL 結果を追加する。
  • 1 つのクエリの変数型と結果型を生成し、コンポーネントの横に貼り付ける。

使い方

  1. GraphQL Schema エディターにスキーマの SDL を貼り付けます。
  2. 使うオペレーションを Document エディターに入力します。スキーマの型だけが必要なら空にします。
  3. // @flow で始まる出力をコピーし、Flow 管理下の .js ファイルに入れます。

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 }
}

Flow 型

// @flow
…
export type User = {|
  __typename?: "User",
  id: $ElementType<Scalars, "ID">,
  name?: ?$ElementType<Scalars, "String">,
  tags: Array<$ElementType<Scalars, "String">>,
|}

export type GetUserQueryVariables = {
  id: $ElementType<Scalars, "ID">,
}

export type GetUserQuery = {
  ...{ __typename?: "Query" },
  ...{|
    user?: ?{
      ...{ __typename?: "User" },
      ...$Pick<User, {| id: *, name?: * |}>,
    },
  |},
}

仕様と制限

フィールドは $ElementType<Scalars, "ID"> の形でスカラーを参照します。先頭の Scalars 型(上の例では省略)は ID と String を string に、Int と Float を number に対応付けます。

オペレーションの結果型はオブジェクトのスプレッドとローカルの $Pick ヘルパーで組み立てられるため、選択したフィールドだけが現れます。

生成はブラウザの Web Worker で実行され、結果は Prettier で整形されます。ページにプラグインオプションはありません。

FAQ

生成されるオブジェクト型は exact ですか?

はい。スキーマのオブジェクト型は exact オブジェクト構文 {| ... |} を使うため、余分なプロパティは Flow でエラーになります。

nullable なフィールドはどう表現されますか?

nullable なフィールドは maybe 型の省略可能プロパティになります。例:name?: ?$ElementType<Scalars, "String">。non-null のフィールドは必須で、maybe 型になりません。

出力に "Document ignored" というコメントがあるのはなぜですか?

Document エディターのオペレーションはスキーマに対して検証されます。合わない場合(デフォルトの例は username をクエリしています)はスキーマの型だけが生成され、最初のエラーが // @flow の下にコメントとして出ます。ドキュメントを修正するか空にしてください。

仕様を確認する