GraphQL to TypeScript Resolvers
GraphQL Fullstack Engineering & Resolver Typing Suite

GraphQL SDLからTypeScriptリゾルバー型生成ツール 開発者ガイド

GraphQL SDL(スキーマ定義言語)から、完全な型安全性を備えたTypeScriptリゾルバーインターフェース、引数型、コンテキスト型を自動生成します。

Zero Server Transmission
Presets:
リゾルバー生成オプション
GraphQL スキーマ定義 (SDL)
114 lines•1901 chars•1901 B
Valid GraphQL AST
/* =============================================================================
 * AUTOMATICALLY GENERATED GRAPHQL RESOLVER TYPES
 * Engine: ToolsAA GraphQL-to-TypeScript Resolvers V3
 * Mode: APOLLO / Pure Client-Side Type Synthesis
 * ============================================================================= */

Maybe<T> = T | null | undefined;
Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] };
MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> };
MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> };
RequireFields<T, K extends keyof T> = Omit<T, K> & { [P in K]-?: NonNullable<T[P]> };

ResolverFn<TResult, TParent, TContext, TArgs> = (
  parent: TParent,
  args: TArgs,
  context: TContext,
  info: any
) => Promise<TResult> | TResult;

Resolver<TResult, TParent = {}, TContext = {}, TArgs = {}> =
  | ResolverFn<TResult, TParent, TContext, TArgs>
  | { resolve: ResolverFn<TResult, TParent, TContext, TArgs> };

SubscriptionSubscribeFn<TResult, TParent, TContext, TArgs> = (
  parent: TParent,
  args: TArgs,
  context: TContext,
  info: any
) => AsyncIterator<TResult> | Promise<AsyncIterator<TResult>>;

SubscriptionResolveFn<TResult, TParent, TContext, TArgs> = (
  parent: TParent,
  args: TArgs,
  context: TContext,
  info: any
) => TResult | Promise<TResult>;

SubscriptionSubscriberObject<TResult, TKey extends string, TParent, TContext, TArgs> {
  subscribe: SubscriptionSubscribeFn<{ [key in TKey]: TResult }, TParent, TContext, TArgs>;
  resolve?: SubscriptionResolveFn<TResult, { [key in TKey]: TResult }, TContext, TArgs>;
}

SubscriptionResolver<TResult, TKey extends string, TParent = {}, TContext = {}, TArgs = {}> =
  | ((...args: any[]) => SubscriptionSubscriberObject<TResult, TKey, TParent, TContext, TArgs>)
  | SubscriptionSubscriberObject<TResult, TKey, TParent, TContext, TArgs>;

TypeResolveFn<TTypes, TParent = {}, TContext = {}> = (
  parent: TParent,
  context: TContext,
  info: any
) => Maybe<TTypes> | Promise<Maybe<TTypes>>;

IsTypeOfResolverFn<T = {}, TContext = {}> = (
  obj: T,
  context: TContext,
  info: any
) => boolean | Promise<boolean>;

/** All built-in and configured custom scalar mapping */
Scalars = {
  ID: { input: string; output: string };
  String: { input: string; output: string };
  Boolean: { input: boolean; output: boolean };
  Int: { input: number; output: number };
  Float: { input: number; output: number };
  DateTime: { input: Date | string; output: Date | string };
  Date: { input: Date | string; output: Date | string };
  Time: { input: string; output: string };
  JSON: { input: any; output: any };
  JSONObject: { input: Record<string, any>; output: Record<string, any> };
  Decimal: { input: string | number; output: string | number };
  UUID: { input: string; output: string };
  Upload: { input: File | Blob; output: File | Blob };

};

/* ==================== ENUMS ==================== */

UserRole {
  ADMIN = 'ADMIN',
  CUSTOMER = 'CUSTOMER',
  FULFILLMENT = 'FULFILLMENT',
}

OrderStatus {
  PENDING = 'PENDING',
  PROCESSING = 'PROCESSING',
  SHIPPED = 'SHIPPED',
  DELIVERED = 'DELIVERED',
  CANCELLED = 'CANCELLED',
}

/* ==================== TYPE MAPPERS ==================== */

/** Mapping of GraphQL types to internal resolver return types */
ResolversTypes = {
  ID: Scalars['ID']['output'];
  String: Scalars['String']['output'];
  Boolean: Scalars['Boolean']['output'];
  Int: Scalars['Int']['output'];
  Float: Scalars['Float']['output'];
  DateTime: Scalars['DateTime']['output'];
  Date: Scalars['Date']['output'];
  Time: Scalars['Time']['output'];
  JSON: Scalars['JSON']['output'];
  JSONObject: Scalars['JSONObject']['output'];
  Decimal: Scalars['Decimal']['output'];
  UUID: Scalars['UUID']['output'];
  Upload: Scalars['Upload']['output'];
  UserRole: UserRole;
  OrderStatus: OrderStatus;
  SearchResult: ResolversTypes['Product'] | ResolversTypes['User'] | ResolversTypes['Order'];
  Node: ResolversTypes['User'] | ResolversTypes['Product'] | ResolversTypes['Order'];
  Timestamps: ResolversTypes['User'] | ResolversTypes['Product'] | ResolversTypes['Order'];
  User: UserModel;
  Product: ProductModel;
  Order: OrderModel;
  OrderItem: OrderItemModel;
  Address: AddressModel;
  Query: {};
  Mutation: {};
};

/** Mapping of GraphQL types to parent/root argument types passed to field resolvers */
ResolversParentTypes = {
  ID: Scalars['ID']['output'];
  String: Scalars['String']['output'];
  Boolean: Scalars['Boolean']['output'];
  Int: Scalars['Int']['output'];
  Float: Scalars['Float']['output'];
  DateTime: Scalars['DateTime']['output'];
  Date: Scalars['Date']['output'];
  Time: Scalars['Time']['output'];
  JSON: Scalars['JSON']['output'];
  JSONObject: Scalars['JSONObject']['output'];
  Decimal: Scalars['Decimal']['output'];
  UUID: Scalars['UUID']['output'];
  Upload: Scalars['Upload']['output'];
  UserRole: UserRole;
  OrderStatus: OrderStatus;
  SearchResult: ResolversParentTypes['Product'] | ResolversParentTypes['User'] | ResolversParentTypes['Order'];
  Node: ResolversParentTypes['User'] | ResolversParentTypes['Product'] | ResolversParentTypes['Order'];
  Timestamps: ResolversParentTypes['User'] | ResolversParentTypes['Product'] | ResolversParentTypes['Order'];
  User: UserModel;
  Product: ProductModel;
  Order: OrderModel;
  OrderItem: OrderItemModel;
  Address: AddressModel;
  Query: {};
  Mutation: {};
};

/* ==================== ENTITY MODEL INTERFACES ==================== */

/** Represents a customer or admin account in the storefront. */
UserModel {
  id: Scalars['ID']['output'];
  email: Scalars['String']['output'];
  displayName: Scalars['String']['output'];
  role: UserRole;
  orders: Array<ResolversTypes['Order']>;
  defaultAddress?: Maybe<ResolversTypes['Address']>;
  createdAt: Scalars['DateTime']['output'];
  updatedAt?: Maybe<Scalars['DateTime']['output']>;
}

ProductModel {
  id: Scalars['ID']['output'];
  sku: Scalars['String']['output'];
  title: Scalars['String']['output'];
  price: Scalars['Float']['output'];
  inventoryCount: Scalars['Int']['output'];
  tags: Array<Scalars['String']['output']>;
  createdAt: Scalars['DateTime']['output'];
  updatedAt?: Maybe<Scalars['DateTime']['output']>;
}

OrderModel {
  id: Scalars['ID']['output'];
  orderNumber: Scalars['String']['output'];
  customer: ResolversTypes['User'];
  status: OrderStatus;
  items: Array<ResolversTypes['OrderItem']>;
  totalAmount: Scalars['Float']['output'];
  shippingAddress: ResolversTypes['Address'];
  createdAt: Scalars['DateTime']['output'];
  updatedAt?: Maybe<Scalars['DateTime']['output']>;
}

OrderItemModel {
  id: Scalars['ID']['output'];
  product: ResolversTypes['Product'];
  quantity: Scalars['Int']['output'];
  unitPrice: Scalars['Float']['output'];
}

AddressModel {
  street: Scalars['String']['output'];
  city: Scalars['String']['output'];
  postalCode: Scalars['String']['output'];
  country: Scalars['String']['output'];
}

/* ==================== RESOLVERS INTERFACES ==================== */

/** Represents a customer or admin account in the storefront. */
UserResolvers<ContextType = AppContext, ParentType extends ResolversParentTypes['User'] = ResolversParentTypes['User']> {
  id?: Resolver<Scalars['ID']['output'], ParentType, ContextType, {}>;
  email?: Resolver<Scalars['String']['output'], ParentType, ContextType, {}>;
  displayName?: Resolver<Scalars['String']['output'], ParentType, ContextType, {}>;
  role?: Resolver<UserRole, ParentType, ContextType, {}>;
  orders?: Resolver<Array<ResolversTypes['Order']>, ParentType, ContextType, UserOrdersArgs>;
  defaultAddress?: Resolver<Maybe<ResolversTypes['Address']>, ParentType, ContextType, {}>;
  createdAt?: Resolver<Scalars['DateTime']['output'], ParentType, ContextType, {}>;
  updatedAt?: Resolver<Maybe<Scalars['DateTime']['output']>, ParentType, ContextType, {}>;
  __isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
}

ProductResolvers<ContextType = AppContext, ParentType extends ResolversParentTypes['Product'] = ResolversParentTypes['Product']> {
  id?: Resolver<Scalars['ID']['output'], ParentType, ContextType, {}>;
  sku?: Resolver<Scalars['String']['output'], ParentType, ContextType, {}>;
  title?: Resolver<Scalars['String']['output'], ParentType, ContextType, {}>;
  price?: Resolver<Scalars['Float']['output'], ParentType, ContextType, {}>;
  inventoryCount?: Resolver<Scalars['Int']['output'], ParentType, ContextType, {}>;
  tags?: Resolver<Array<Scalars['String']['output']>, ParentType, ContextType, {}>;
  createdAt?: Resolver<Scalars['DateTime']['output'], ParentType, ContextType, {}>;
  updatedAt?: Resolver<Maybe<Scalars['DateTime']['output']>, ParentType, ContextType, {}>;
  __isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
}

OrderResolvers<ContextType = AppContext, ParentType extends ResolversParentTypes['Order'] = ResolversParentTypes['Order']> {
  id?: Resolver<Scalars['ID']['output'], ParentType, ContextType, {}>;
  orderNumber?: Resolver<Scalars['String']['output'], ParentType, ContextType, {}>;
  customer?: Resolver<ResolversTypes['User'], ParentType, ContextType, {}>;
  status?: Resolver<OrderStatus, ParentType, ContextType, {}>;
  items?: Resolver<Array<ResolversTypes['OrderItem']>, ParentType, ContextType, {}>;
  totalAmount?: Resolver<Scalars['Float']['output'], ParentType, ContextType, {}>;
  shippingAddress?: Resolver<ResolversTypes['Address'], ParentType, ContextType, {}>;
  createdAt?: Resolver<Scalars['DateTime']['output'], ParentType, ContextType, {}>;
  updatedAt?: Resolver<Maybe<Scalars['DateTime']['output']>, ParentType, ContextType, {}>;
  __isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
}

OrderItemResolvers<ContextType = AppContext, ParentType extends ResolversParentTypes['OrderItem'] = ResolversParentTypes['OrderItem']> {
  id?: Resolver<Scalars['ID']['output'], ParentType, ContextType, {}>;
  product?: Resolver<ResolversTypes['Product'], ParentType, ContextType, {}>;
  quantity?: Resolver<Scalars['Int']['output'], ParentType, ContextType, {}>;
  unitPrice?: Resolver<Scalars['Float']['output'], ParentType, ContextType, {}>;
  __isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
}

AddressResolvers<ContextType = AppContext, ParentType extends ResolversParentTypes['Address'] = ResolversParentTypes['Address']> {
  street?: Resolver<Scalars['String']['output'], ParentType, ContextType, {}>;
  city?: Resolver<Scalars['String']['output'], ParentType, ContextType, {}>;
  postalCode?: Resolver<Scalars['String']['output'], ParentType, ContextType, {}>;
  country?: Resolver<Scalars['String']['output'], ParentType, ContextType, {}>;
  __isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
}

QueryResolvers<ContextType = AppContext, ParentType extends ResolversParentTypes['Query'] = ResolversParentTypes['Query']> {
  me?: Resolver<Maybe<ResolversTypes['User']>, ParentType, ContextType, {}>;
  user?: Resolver<Maybe<ResolversTypes['User']>, ParentType, ContextType, RequireFields<QueryUserArgs, 'id'>>;
  product?: Resolver<Maybe<ResolversTypes['Product']>, ParentType, ContextType, RequireFields<QueryProductArgs, 'id'>>;
  products?: Resolver<Array<ResolversTypes['Product']>, ParentType, ContextType, QueryProductsArgs>;
  search?: Resolver<Array<ResolversTypes['SearchResult']>, ParentType, ContextType, RequireFields<QuerySearchArgs, 'query'>>;
}

MutationResolvers<ContextType = AppContext, ParentType extends ResolversParentTypes['Mutation'] = ResolversParentTypes['Mutation']> {
  createProduct?: Resolver<ResolversTypes['Product'], ParentType, ContextType, RequireFields<MutationCreateProductArgs, 'input'>>;
  checkoutCart?: Resolver<ResolversTypes['Order'], ParentType, ContextType, RequireFields<MutationCheckoutCartArgs, 'input'>>;
  cancelOrder?: Resolver<ResolversTypes['Order'], ParentType, ContextType, RequireFields<MutationCancelOrderArgs, 'orderId'>>;
}

SearchResultResolvers<ContextType = AppContext, ParentType extends ResolversParentTypes['SearchResult'] = ResolversParentTypes['SearchResult']> {
  __resolveType: TypeResolveFn<'Product' | 'User' | 'Order', ParentType, ContextType>;
}

NodeResolvers<ContextType = AppContext, ParentType extends ResolversParentTypes['Node'] = ResolversParentTypes['Node']> {
  __resolveType: TypeResolveFn<'User' | 'Product' | 'Order', ParentType, ContextType>;
}

TimestampsResolvers<ContextType = AppContext, ParentType extends ResolversParentTypes['Timestamps'] = ResolversParentTypes['Timestamps']> {
  __resolveType: TypeResolveFn<'User' | 'Product' | 'Order', ParentType, ContextType>;
}

/** Top-level combined resolvers map passed to your GraphQL server setup */
Resolvers<ContextType = AppContext> {
  User?: UserResolvers<ContextType>;
  Product?: ProductResolvers<ContextType>;
  Order?: OrderResolvers<ContextType>;
  OrderItem?: OrderItemResolvers<ContextType>;
  Address?: AddressResolvers<ContextType>;
  Query?: QueryResolvers<ContextType>;
  Mutation?: MutationResolvers<ContextType>;
  SearchResult?: SearchResultResolvers<ContextType>;
  Node?: NodeResolvers<ContextType>;
  Timestamps?: TimestampsResolvers<ContextType>;
}
299 lines•13141 chars•13141 B
Parsed in 0ms (Pure Browser)
解析済み型定義15 TypesSDL AST から抽出されたオブジェクト・インターフェース・ユニオン・Enum の総数
リゾルバーフィールド9 Fields生成された強型付けリゾルバー関数と引数インターフェースの総数
完全ローカル実行100% Client-Sideサーバー送信ゼロ、ブラウザのメモリ内だけで瞬時にコード生成

GraphQL 公式仕様に完全準拠

Query・Mutation・Subscription・Input・Interface・Union・Directive を高精度な AST 構文木で忠実に解析します。

ゼロレイテンシのブラウザ内型推論

字句解析および TypeScript 生成処理はすべてブラウザ内で完結。機密スキーマが外部サーバーに送信されることはありません。

プロダクション対応のフルスタック型統合

Apollo Server、GraphQL Yoga、Mercurius に対応したルートリゾルバー、親マッパー、引数型を即座に生成可能です。

技術リファレンス&アーキテクチャガイド

GraphQL SDLからTypeScriptリゾルバー型生成ツール 開発者ガイド — リファレンスガイド

GraphQL SDL(スキーマ定義言語)から、完全な型安全性を備えたTypeScriptリゾルバーインターフェース、引数型、コンテキスト型を自動生成します。

主要パラメータ&設定項目

コンテキスト型名 (Context Type Name)string

すべてのリゾルバー関数の第3引数として渡される共有コンテキストオブジェクトの型名(例: GraphQLContext)。

初期値: GraphQLContext
リゾルバー戻り値のラップ戦略 (Resolver Return Wrapper)Enum (PromiseOrValue | PromiseOnly | DirectValue)

リゾルバーの実行結果に対する型ラッピング設定(T | Promise<T>、Promise<T>のみ、または直接値)。

初期値: PromiseOrValue
ルート親オブジェクトの型付け (Root Parent Typing)Enum (unknown | undefined | empty_object)

ルートクエリ(Query)やミューテーション(Mutation)の第1引数(parent/source)に適用する型。

初期値: unknown
カスタムスカラーマッピング (Custom Scalar Mapping)Record<string, string>

DateTimeやJSON、UUIDなどのGraphQLカスタムスカラーに対するTypeScript型の対応設定。

初期値: {"DateTime": "string | Date", "JSON": "Record<string, unknown>"}

プロの活用テクニック&推奨設定

DataLoaderとの連携によるN+1問題の防止

コンテキスト型内に型付けされたDataLoaderインスタンスを定義することで、ネストしたフィールドリゾルバー内で安全なバッチデータ取得を実現できます。

ネストされたリゾルバーにおける親オブジェクト型の活用

ネストされたリゾルバーは親オブジェクトの解決済みデータ型(UserParentなど)を第1引数として自動推論し、プロパティ参照エラーを防ぎます。

文字列リテラル型によるランタイムオーバーヘッドの排除

GraphQL EnumをTypeScriptの数値Enumではなく文字列リテラルユニオン型として生成することで、JSコードの肥大化を防ぎツリーシェイキングを最適化できます。

よくあるトラブルと解決策

リゾルバー関数の戻り値とGraphQLスキーマの型定義が一致せず型エラーになる

リゾルバーがスキーマのNull許容性や配列定義に合致する型、またはそのPromiseを返しているか確認してください。

未マッピングのカスタムスカラーがany型として出力される

スカラーマッピング設定で、スキーマ内で宣言されているカスタムスカラー(DateTime -> string | Dateなど)に明示的なTypeScript型を割り当ててください。

よくある質問 (FAQ)

クライアント向けのGraphQL型とバックエンドのリゾルバー型の違いは何ですか?▼

クライアント型はクエリ結果のレスポンス形状を表すのに対し、リゾルバー型は(parent, args, context, info) => Tというサーバー側の実行関数シグネチャを厳格に定義します。

Apollo ServerやGraphQL Yoga、Mercuriusなどの主要フレームワークで使用できますか?▼

はい。標準的なGraphQL-JSの実行仕様に準拠しているため、makeExecutableSchemaやApolloServer、createYogaの設定オブジェクトに直接適用可能です。

GraphQLのNull許容・非Nullフィールドはどのように変換されますか?▼

!が付いた非Nullフィールドは必須の戻り値型となり、!のないフィールドはT | null | undefinedとして厳格に型付けされます。

入力した機密スキーマが外部サーバーに送信されることはありますか?▼

いいえ。ASTの構文解析からTypeScriptコードの生成まですべてブラウザ内で完結し、外部サーバーへの通信は一切発生しません。

関連するおすすめ開発ツール

すべてのツール →
cURL to C# 変換ツール (.NET HttpClient, RestSharp & Flurl) 開発者ガイドdeveloper

コマンドラインの cURL リクエストを、.NET HttpClient、RestSharp、Flurl.Http を用いた実用的な C# コードへ高精度に変換。非同期処理や接続プーリングのベストプラクティスに対応。

ツールを開く→
cURLからJavaへの変換ガイド(Java 11+ HttpClient、OkHttp & Spring WebClient)developer

cURLコマンドを標準のjava.net.http.HttpClient、OkHttp3、Spring WebClientのプロダクション品質なJavaコードへ瞬時に変換します。

ツールを開く→
JSON から XML Schema (XSD) 定義ジェネレーター 開発者ガイドdeveloper

サンプルJSONからXMLスキーマ定義(XSD)の型構造、複合要素(complexType)、属性、出現頻度(minOccurs/maxOccurs)を高精度に自動推論。

ツールを開く→
インタラクティブ .gitignore ファイル生成ツール (Node, Python, Go, Rust, Java) 開発者ガイドdeveloper

OS、IDE、および50以上の主要プログラミング言語の除外ルールを組み合わせ、包括的な .gitignore テンプレートを瞬時に生成します。

ツールを開く→
Crontab構文&Quartzスケジュール式 チートシートdeveloper

5フィールドPOSIX規格および6フィールドQuartz形式のcron式完全リファレンス。特殊マクロ、実行周期計算、多重起動防止策を徹底解説。

ツールを開く→
JavaScript正規表現(RegEx)構文仕様・チートシートdeveloper

ECMAScript準拠の正規表現構文、キャプチャグループ(名前付き・非キャプチャ)、置換トークン($1, $&)、先読み・後読みの技術解説。

ツールを開く→