GraphQL to TypeScript Resolvers
GraphQL Fullstack Engineering & Resolver Typing Suite

GraphQL SDL zu TypeScript Resolver-Typen Generator Entwicklerhandbuch

Generieren Sie typsichere TypeScript-Resolver-Interfaces, Query-/Mutation-Argumente und Parent-Kontexttypen aus GraphQL SDL.

Zero Server Transmission
Presets:
Generator-Optionen
GraphQL Schemadefinition (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 7ms (Pure Browser)
Typen analysiert15 TypesObjekt-, Schnittstellen-, Union- und Enum-Definitionen im AST erkannt
Resolver-Felder9 FieldsTypsichere Resolver-Signaturen und Argumenten-Interfaces generiert
Keine Serverabhängigkeit100% Client-SideVollständig clientseitig im Browser-Speicher ohne Netzwerkübertragung

Vollständige GraphQL-Spezifikationskonformität

Parst Queries, Mutations, Subscriptions, Interfaces, Unions und benutzerdefinierte Direktiven präzise und fehlerfrei.

Lokale Typensynthese ohne Latenz

Sämtliche Tokenisierung und Codegenerierung erfolgt lokal im Browser. Keine Schemadaten verlassen Ihr System.

Produktionsbereite Typensicherheit

Unterstützt Apollo Server, GraphQL Yoga und Mercurius mit flexiblen Parent-Mappern und Kontexttypen.

Technische Referenz & Architektur-Leitfaden

GraphQL SDL zu TypeScript Resolver-Typen Generator Entwicklerhandbuch — Referenz-Leitfaden

Generieren Sie typsichere TypeScript-Resolver-Interfaces, Query-/Mutation-Argumente und Parent-Kontexttypen aus GraphQL SDL.

Wichtige Parameter & Steuerelemente

Kontext-Typname (Context Type Name)string

Der Bezeichner für das gemeinsame Kontextobjekt, das als dritter Parameter an alle Resolver-Funktionen übergeben wird.

Standard: GraphQLContext
Resolver-Rückgabetyp-Wrapper (Resolver Return Wrapper)Enum (PromiseOrValue | PromiseOnly | DirectValue)

Verpackungsstrategie für Resolver-Ergebnisse (z. B. T | Promise<T> versus reines Promise<T>).

Standard: PromiseOrValue
Root-Parent-Typisierung (Root Parent Typing)Enum (unknown | undefined | empty_object)

Typisierungsstrategie für den ersten Parameter (parent/source) bei Root-Query- und Mutation-Feldern.

Standard: unknown
Benutzerdefinierte Skalar-Zuordnung (Custom Scalar Mapping)Record<string, string>

TypeScript-Typbindungen für benutzerdefinierte GraphQL-Skalare wie DateTime, JSON und UUID.

Standard: {"DateTime": "string | Date", "JSON": "Record<string, unknown>"}

Profi-Tipps & Best Practices

Kombination mit DataLoader zur Vermeidung von N+1-Abfragen

Typisieren Sie Ihr Kontextobjekt mit typsicheren DataLoader-Instanzen, damit verschachtelte Resolver typisierte Batch-Methoden nutzen können.

Parent-Typisierung für verschachtelte Resolver nutzen

Verschachtelte Resolver leiten die aufgelöste Form des übergeordneten Objekts (z. B. UserParent) ab und verhindern fehlerhaften Eigenschaftszugriff.

String-Literal-Unions für Enum-Definitionen bevorzugen

Verwenden Sie String-Unions anstelle von TypeScript-Enums, um Runtime-Overhead im kompilierten JavaScript zu vermeiden und Tree-Shaking zu optimieren.

Häufige Fallstricke & Fehlerbehebung

Typenkonflikt zwischen Resolver-Rückgabe und Schema-Felddefinition

Stellen Sie sicher, dass der Resolver exakt den geforderten Typ oder ein entsprechendes Promise zurückgibt und Nullierbarkeitsregeln einhält.

Nicht zugeordnete Skalare fallen auf 'any' zurück oder verursachen Kompilierfehler

Definieren Sie in den Skalareinstellungen explizite Zuordnungen für alle im SDL definierten Skalare (z. B. DateTime -> string | Date).

Häufig gestellte Fragen (FAQ)

Was ist der Unterschied zwischen clientseitigen GraphQL-Typen und Backend-Resolver-Typen?▼

Client-Typen beschreiben die Datenstruktur von Abfrageantworten, während Resolver-Typen die serverseitigen Ausführungsfunktionen (parent, args, context, info) => T typisieren.

Ist der generierte Code mit Apollo Server, GraphQL Yoga und Mercurius kompatibel?▼

Ja. Das generierte Resolver-Interface folgt dem Standard-GraphQL-JS-Muster und kann direkt an makeExecutableSchema oder ApolloServer übergeben werden.

Wie werden Nullable- und Non-Null-Felder (!) übersetzt?▼

Felder mit '!' erfordern zwingende Rückgabetypen, während Felder ohne Ausrufezeichen als T | null | undefined typisiert werden.

Werden meine GraphQL-Schema-Dateien an einen externen Server gesendet?▼

Nein. Das Parsing, die AST-Analyse und die Codegenerierung erfolgen zu 100 % lokal in Ihrem Browser ohne Netzwerkübertragung.

Verwandte Werkzeuge & Dienstprogramme

Alle Werkzeuge →