Object Types
Object types are the most common type in GraphQL. They represent a type with a set of fields that you can query. In @graphql-ts/schema, you can define object types using the g.object function.
To define an object type, you need to provide a source type that represents the shape of the object type on the server. Note this type doesn’t have to align with the GraphQL fields.
type type UserSource = { id: string; name: string;}
UserSource = { id: string
id: string; name: string
name: string;};
const const User: GObjectType<UserSource, unknown>
User = const g: GWithContext<unknown>
g.object: <UserSource>(youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction?: { youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction: true;}) => <Fields, Interfaces>(config: { ...;} & Omit<...>) => GObjectType<...>
object<type UserSource = { id: string; name: string;}
UserSource>()({ name: string
name: "User",});Then we can define the fields of the object type. The fields object is a map of field names to field definitions. The field definitions are created using the g.field function.
const const User: GObjectType<UserSource, unknown>
User = const g: GWithContext<unknown>
g.object: <UserSource>(youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction?: { youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction: true;}) => <Fields, Interfaces>(config: { ...;} & Omit<...>) => GObjectType<...>
object<type UserSource = { id: string; name: string;}
UserSource>()({ name: string
name: "User", fields: { id: GField<UserSource, any, GNonNull<GScalarType<string, string>>, ImpliedResolver<any, GNonNull<GScalarType<string, string>>, unknown>, unknown>; name: GField<...>;} | (() => { id: GField<UserSource, any, GNonNull<GScalarType<string, string>>, ImpliedResolver<any, GNonNull<GScalarType<string, string>>, unknown>, unknown>; name: GField<...>;})
fields: { id: GField<UserSource, any, GNonNull<GScalarType<string, string>>, ImpliedResolver<any, GNonNull<GScalarType<string, string>>, unknown>, unknown>
id: const g: GWithContext<unknown>
g.field: <UserSource, GNonNull<GScalarType<string, string>>, unknown, any>(field: FieldFuncArgs<UserSource, any, GNonNull<GScalarType<string, string>>, unknown> & { ...;}) => GField<...>
field({ type: GNonNull<GScalarType<string, string>>
type: const g: GWithContext<unknown>
g.nonNull: <GScalarType<string, string>>(of: GScalarType<string, string>) => GNonNull<GScalarType<string, string>>
nonNull(const g: GWithContext<unknown>
g.type ID: GScalarType<string, string>
ID) }), name: GField<UserSource, any, GNonNull<GScalarType<string, string>>, ImpliedResolver<any, GNonNull<GScalarType<string, string>>, unknown>, unknown>
name: const g: GWithContext<unknown>
g.field: <UserSource, GNonNull<GScalarType<string, string>>, unknown, any>(field: FieldFuncArgs<UserSource, any, GNonNull<GScalarType<string, string>>, unknown> & { ...;}) => GField<...>
field({ type: GNonNull<GScalarType<string, string>>
type: const g: GWithContext<unknown>
g.nonNull: <GScalarType<string, string>>(of: GScalarType<string, string>) => GNonNull<GScalarType<string, string>>
nonNull(const g: GWithContext<unknown>
g.type String: GScalarType<string, string>
String) }), },});type User { id: ID! name: String!}Since the UserSource type in this case aligns with the GraphQL fields, we don’t need to provide a resolve function for the fields. This isn’t always the case though, if we add a field that doesn’t exist on the UserSource type, we’ll receive a TypeScript error:
const const User: GObjectType<UserSource, unknown>
User = const g: GWithContext<unknown>
g.object: <UserSource>(youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction?: { youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction: true;}) => <Fields, Interfaces>(config: { ...;} & Omit<...>) => GObjectType<...>
object<type UserSource = { id: string; name: string;}
UserSource>()({ name: string
name: "User", fields: ({ id: GField<UserSource, any, any, string, unknown>; name: GField<UserSource, any, any, string, unknown>; nameBackwards: GField<UserSource, any, any, unknown, unknown>;} & InterfaceFieldsToOutputFields<...>) | (() => { id: GField<UserSource, any, any, string, unknown>; name: GField<UserSource, any, any, string, unknown>; nameBackwards: GField<UserSource, any, any, unknown, unknown>;} & InterfaceFieldsToOutputFields<...>)
fields: { id: GField<UserSource, any, any, string, unknown>
id: const g: GWithContext<unknown>
g.field: <UserSource, GNonNull<GScalarType<string, string>>, unknown, any>(field: FieldFuncArgs<UserSource, any, GNonNull<GScalarType<string, string>>, unknown> & { ...;}) => GField<...>
field({ type: GNonNull<GScalarType<string, string>>
type: const g: GWithContext<unknown>
g.nonNull: <GScalarType<string, string>>(of: GScalarType<string, string>) => GNonNull<GScalarType<string, string>>
nonNull(const g: GWithContext<unknown>
g.type ID: GScalarType<string, string>
ID) }), name: GField<UserSource, any, GNonNull<GScalarType<string, string>>, ImpliedResolver<any, GNonNull<GScalarType<string, string>>, unknown>, unknown>
name: const g: GWithContext<unknown>
g.field: <UserSource, GNonNull<GScalarType<string, string>>, unknown, any>(field: FieldFuncArgs<UserSource, any, GNonNull<GScalarType<string, string>>, unknown> & { ...;}) => GField<...>
field({ type: GNonNull<GScalarType<string, string>>
type: const g: GWithContext<unknown>
g.nonNull: <GScalarType<string, string>>(of: GScalarType<string, string>) => GNonNull<GScalarType<string, string>>
nonNull(const g: GWithContext<unknown>
g.type String: GScalarType<string, string>
String) }), nameBackwards: const g: GWithContext<unknown>
g.field: <UserSource, GNonNull<GScalarType<string, string>>, unknown, any>(field: FieldFuncArgs<UserSource, any, GNonNull<GScalarType<string, string>>, unknown> & { ...;}) => GField<...>
field({ type: GNonNull<GScalarType<string, string>>
type: const g: GWithContext<unknown>
g.nonNull: <GScalarType<string, string>>(of: GScalarType<string, string>) => GNonNull<GScalarType<string, string>>
nonNull(const g: GWithContext<unknown>
g.type String: GScalarType<string, string>
String) }),Error ts(2375) ― },});type User { id: ID! name: String! nameBackwards: String!}This is telling us that we need to provide a resolve function for the nameBackwards field. The resolve function recieves the source type that we provided when creating the object type. This allows us to calculate the value of the field based on the source type.
const const User: GObjectType<UserSource, unknown>
User = const g: GWithContext<unknown>
g.object: <UserSource>(youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction?: { youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction: true;}) => <Fields, Interfaces>(config: { ...;} & Omit<...>) => GObjectType<...>
object<type UserSource = { id: string; name: string;}
UserSource>()({ name: string
name: "User", fields: { id: GField<UserSource, any, GNonNull<GScalarType<string, string>>, ImpliedResolver<any, GNonNull<GScalarType<string, string>>, unknown>, unknown>; name: GField<...>; nameBackwards: GField<...>;} | (() => { id: GField<UserSource, any, GNonNull<GScalarType<string, string>>, ImpliedResolver<any, GNonNull<GScalarType<string, string>>, unknown>, unknown>; name: GField<...>; nameBackwards: GField<...>;})
fields: { id: GField<UserSource, any, GNonNull<GScalarType<string, string>>, ImpliedResolver<any, GNonNull<GScalarType<string, string>>, unknown>, unknown>
id: const g: GWithContext<unknown>
g.field: <UserSource, GNonNull<GScalarType<string, string>>, unknown, any>(field: FieldFuncArgs<UserSource, any, GNonNull<GScalarType<string, string>>, unknown> & { ...;}) => GField<...>
field({ type: GNonNull<GScalarType<string, string>>
type: const g: GWithContext<unknown>
g.nonNull: <GScalarType<string, string>>(of: GScalarType<string, string>) => GNonNull<GScalarType<string, string>>
nonNull(const g: GWithContext<unknown>
g.type ID: GScalarType<string, string>
ID) }), name: GField<UserSource, any, GNonNull<GScalarType<string, string>>, ImpliedResolver<any, GNonNull<GScalarType<string, string>>, unknown>, unknown>
name: const g: GWithContext<unknown>
g.field: <UserSource, GNonNull<GScalarType<string, string>>, unknown, any>(field: FieldFuncArgs<UserSource, any, GNonNull<GScalarType<string, string>>, unknown> & { ...;}) => GField<...>
field({ type: GNonNull<GScalarType<string, string>>
type: const g: GWithContext<unknown>
g.nonNull: <GScalarType<string, string>>(of: GScalarType<string, string>) => GNonNull<GScalarType<string, string>>
nonNull(const g: GWithContext<unknown>
g.type String: GScalarType<string, string>
String) }), nameBackwards: GField<UserSource, any, GNonNull<GScalarType<string, string>>, unknown, unknown>
nameBackwards: const g: GWithContext<unknown>
g.field: <UserSource, GNonNull<GScalarType<string, string>>, (source: UserSource) => string, any>(field: FieldFuncArgs<UserSource, any, GNonNull<...>, unknown> & { ...;}) => GField<...>
field({ type: GNonNull<GScalarType<string, string>>
type: const g: GWithContext<unknown>
g.nonNull: <GScalarType<string, string>>(of: GScalarType<string, string>) => GNonNull<GScalarType<string, string>>
nonNull(const g: GWithContext<unknown>
g.type String: GScalarType<string, string>
String), resolve: ((source: UserSource, args: {}, context: unknown, info: GraphQLResolveInfo) => InferValueFromOutputType<GNonNull<GScalarType<string, string>>>) & ((source: UserSource) => string)
resolve(source: UserSource
source) { return source: UserSource
source.name: string
name.String.split(separator: string | RegExp, limit?: number): string[] (+1 overload)
split("").Array<string>.reverse(): string[]
reverse().Array<string>.join(separator?: string): string
join(""); }, }), },});type User { id: ID! name: String! nameBackwards: String!}Field Arguments
Fields can also have arguments. Arguments are defined using the args object on the field definition. The args object is a map of argument names to argument definitions. The argument definitions are created using the g.arg function. @graphql-ts/schema will then infer the second parameter to resolve based on the args defintion.
const const User: GObjectType<UserSource, unknown>
User = const g: GWithContext<unknown>
g.object: <UserSource>(youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction?: { youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction: true;}) => <Fields, Interfaces>(config: { ...;} & Omit<...>) => GObjectType<...>
object<type UserSource = { id: string; name: string;}
UserSource>()({ name: string
name: "User", fields: { id: GField<UserSource, any, GNonNull<GScalarType<string, string>>, ImpliedResolver<any, GNonNull<GScalarType<string, string>>, unknown>, unknown>; name: GField<...>; nameWithLength: GField<...>;} | (() => { id: GField<UserSource, any, GNonNull<GScalarType<string, string>>, ImpliedResolver<any, GNonNull<GScalarType<string, string>>, unknown>, unknown>; name: GField<...>; nameWithLength: GField<...>;})
fields: { id: GField<UserSource, any, GNonNull<GScalarType<string, string>>, ImpliedResolver<any, GNonNull<GScalarType<string, string>>, unknown>, unknown>
id: const g: GWithContext<unknown>
g.field: <UserSource, GNonNull<GScalarType<string, string>>, unknown, any>(field: FieldFuncArgs<UserSource, any, GNonNull<GScalarType<string, string>>, unknown> & { ...;}) => GField<...>
field({ type: GNonNull<GScalarType<string, string>>
type: const g: GWithContext<unknown>
g.nonNull: <GScalarType<string, string>>(of: GScalarType<string, string>) => GNonNull<GScalarType<string, string>>
nonNull(const g: GWithContext<unknown>
g.type ID: GScalarType<string, string>
ID) }), name: GField<UserSource, any, GNonNull<GScalarType<string, string>>, ImpliedResolver<any, GNonNull<GScalarType<string, string>>, unknown>, unknown>
name: const g: GWithContext<unknown>
g.field: <UserSource, GNonNull<GScalarType<string, string>>, unknown, any>(field: FieldFuncArgs<UserSource, any, GNonNull<GScalarType<string, string>>, unknown> & { ...;}) => GField<...>
field({ type: GNonNull<GScalarType<string, string>>
type: const g: GWithContext<unknown>
g.nonNull: <GScalarType<string, string>>(of: GScalarType<string, string>) => GNonNull<GScalarType<string, string>>
nonNull(const g: GWithContext<unknown>
g.type String: GScalarType<string, string>
String) }), nameWithLength: GField<UserSource, { length: GArg<GNonNull<GScalarType<number, number>>, false>;}, GNonNull<GScalarType<string, string>>, unknown, unknown>
nameWithLength: const g: GWithContext<unknown>
g.field: <UserSource, GNonNull<GScalarType<string, string>>, (source: UserSource, args: { readonly length: number;}) => string, { length: GArg<...>;}>(field: FieldFuncArgs<...> & { ...;}) => GField<...>
field({ type: GNonNull<GScalarType<string, string>>
type: const g: GWithContext<unknown>
g.nonNull: <GScalarType<string, string>>(of: GScalarType<string, string>) => GNonNull<GScalarType<string, string>>
nonNull(const g: GWithContext<unknown>
g.type String: GScalarType<string, string>
String), args?: { length: GArg<GNonNull<GScalarType<number, number>>, false>;}
args: { length: GArg<GNonNull<GScalarType<number, number>>, false>
length: const g: GWithContext<unknown>
g.arg: <GNonNull<GScalarType<number, number>>, undefined>(arg: { type: GNonNull<GScalarType<number, number>>; description?: Maybe<string>; extensions?: (Readonly<...> & Readonly<...>) | ... 1 more ... | undefined; astNode?: Maybe<...>; deprecationReason?: Maybe<...>;} & { ...;}) => GArg<...>
arg({ type: GNonNull<GScalarType<number, number>>
type: const g: GWithContext<unknown>
g.nonNull: <GScalarType<number, number>>(of: GScalarType<number, number>) => GNonNull<GScalarType<number, number>>
nonNull(const g: GWithContext<unknown>
g.type Int: GScalarType<number, number>
Int) }), }, resolve: ((source: UserSource, args: { readonly length: number;}, context: unknown, info: GraphQLResolveInfo) => InferValueFromOutputType<GNonNull<GScalarType<string, string>>>) & ((source: UserSource, args: { ...;}) => string)
resolve(source: UserSource
source, args: { readonly length: number;}
args) { return source: UserSource
source.name: string
name.String.slice(start?: number, end?: number): string
slice(0, args: { readonly length: number;}
args.l );length }, }), },});type User { id: ID! name: String! nameWithLength(length: Int!): String!}Context
The resolve function is also provided a third argument, the context. This is useful for providing things like database connections, authentication information, etc. The context is defined by the Context type that is passed to gWithContext.
import { function gWithContext<Context>(): GWithContext<Context>
gWithContext } from "@graphql-ts/schema";
type type Context = { loadUser: (id: string) => Promise<UserSource | null>;}
Context = { loadUser: (id: string) => Promise<UserSource | null>
loadUser: (id: string
id: string) => interface Promise<T>
Promise<type UserSource = { id: string; name: string;}
UserSource | null>;};const const g: GWithContext<Context>
g = gWithContext<Context>(): GWithContext<Context>
gWithContext<type Context = { loadUser: (id: string) => Promise<UserSource | null>;}
Context>();type type g<T> = T extends () => (args: any) => infer R ? R : T extends (args: any) => infer R ? R : never
g<function (type parameter) T in type g<T>
T> = (alias) namespace gWithContextimport gWithContext
gWithContext.type gWithContext.infer<T> = T extends () => (args: any) => infer R ? R : T extends (args: any) => infer R ? R : never
infer<function (type parameter) T in type g<T>
T>;
const const Query: GObjectType<unknown, Context>
Query = const g: GWithContext<Context>
g.object: <unknown>(youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction?: { youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction: true;}) => <Fields, Interfaces>(config: { ...;} & Omit<...>) => GObjectType<...>
object()({ name: string
name: "Query", fields: { user: GField<unknown, { id: GArg<GNonNull<GScalarType<string, string>>, false>; }, GObjectType<UserSource, Context>, unknown, Context>;} | (() => { user: GField<unknown, { id: GArg<GNonNull<GScalarType<string, string>>, false>; }, GObjectType<UserSource, Context>, unknown, Context>;})
fields: () => ({ user: GField<unknown, { id: GArg<GNonNull<GScalarType<string, string>>, false>;}, GObjectType<UserSource, Context>, unknown, Context>
user: const g: GWithContext<Context>
g.field: <unknown, GObjectType<UserSource, Context>, (_: unknown, args: { readonly id: string;}, context: Context) => any, { id: GArg<GNonNull<GScalarType<string, string>>, false>;}>(field: FieldFuncArgs<...> & { ...;}) => GField<...>
field({ type: GObjectType<UserSource, Context>
type: const User: GObjectType<UserSource, Context>
User, args?: { id: GArg<GNonNull<GScalarType<string, string>>, false>;}
args: { id: GArg<GNonNull<GScalarType<string, string>>, false>
id: const g: GWithContext<Context>
g.arg: <GNonNull<GScalarType<string, string>>, undefined>(arg: { type: GNonNull<GScalarType<string, string>>; description?: Maybe<string>; extensions?: (Readonly<...> & Readonly<...>) | ... 1 more ... | undefined; astNode?: Maybe<...>; deprecationReason?: Maybe<...>;} & { ...;}) => GArg<...>
arg({ type: GNonNull<GScalarType<string, string>>
type: const g: GWithContext<Context>
g.nonNull: <GScalarType<string, string>>(of: GScalarType<string, string>) => GNonNull<GScalarType<string, string>>
nonNull(const g: GWithContext<Context>
g.type ID: GScalarType<string, string>
ID) }), }, resolve: ((source: unknown, args: { readonly id: string;}, context: Context, info: GraphQLResolveInfo) => InferValueFromOutputType<GObjectType<UserSource, Context>>) & ((_: unknown, args: { ...;}, context: Context) => any)
resolve(_: unknown
_, args: { readonly id: string;}
args, context: Context
context) { return context: Context
context.lo any
loadUser }, }), }),});type Query { user(id: ID!): User}
type User { id: ID! name: String!}Circular Types
Since GraphQL, like the name suggests, is about querying a graph, it’s common to have circular types in your schema where one type references another type that references the first type. To start with, we need to make fields a function that returns a function so we can lazily reference the User type:
const User = const g: GWithContext<unknown>
g.object: <UserSource>(youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction?: { youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction: true;}) => <Fields, Interfaces>(config: { ...;} & Omit<...>) => GObjectType<...>
object<type UserSource = { id: string; name: string;}
UserSource>()({Error ts(7022) ― name: string
name: "User", fields: () => ({Error ts(7023) ― id: GField<UserSource, any, GNonNull<GScalarType<string, string>>, ImpliedResolver<any, GNonNull<GScalarType<string, string>>, unknown>, unknown>
id: const g: GWithContext<unknown>
g.field: <UserSource, GNonNull<GScalarType<string, string>>, unknown, any>(field: FieldFuncArgs<UserSource, any, GNonNull<GScalarType<string, string>>, unknown> & { ...;}) => GField<...>
field({ type: GNonNull<GScalarType<string, string>>
type: const g: GWithContext<unknown>
g.nonNull: <GScalarType<string, string>>(of: GScalarType<string, string>) => GNonNull<GScalarType<string, string>>
nonNull(const g: GWithContext<unknown>
g.type ID: GScalarType<string, string>
ID) }), name: GField<UserSource, any, GNonNull<GScalarType<string, string>>, ImpliedResolver<any, GNonNull<GScalarType<string, string>>, unknown>, unknown>
name: const g: GWithContext<unknown>
g.field: <UserSource, GNonNull<GScalarType<string, string>>, unknown, any>(field: FieldFuncArgs<UserSource, any, GNonNull<GScalarType<string, string>>, unknown> & { ...;}) => GField<...>
field({ type: GNonNull<GScalarType<string, string>>
type: const g: GWithContext<unknown>
g.nonNull: <GScalarType<string, string>>(of: GScalarType<string, string>) => GNonNull<GScalarType<string, string>>
nonNull(const g: GWithContext<unknown>
g.type String: GScalarType<string, string>
String) }), friends: GField<UserSource, any, GList<any>, unknown, unknown>
friends: const g: GWithContext<unknown>
g.field: <UserSource, GList<any>, () => never[], any>(field: FieldFuncArgs<UserSource, any, GList<any>, unknown> & { resolve: ((source: UserSource, args: {}, context: unknown, info: GraphQLResolveInfo) => InferValueFromOutputType<...>) & (() => never[]);}) => GField<...>
field({ type: GList<any>
type: const g: GWithContext<unknown>
g.list: <any>(of: any) => GList<any>
list(const User: any
User), resolve: ((source: UserSource, args: {}, context: unknown, info: GraphQLResolveInfo) => InferValueFromOutputType<GList<any>>) & (() => never[])
resolve: () => [], }), }),});TypeScript doesn’t understand this circularity though, we can fix this by using the g type and the g.object function to be explicit about the type of User:
import { function gWithContext<Context>(): GWithContext<Context>
gWithContext } from "@graphql-ts/schema";const const g: GWithContext<unknown>
g = gWithContext<unknown>(): GWithContext<unknown>
gWithContext();type type g<T> = T extends () => (args: any) => infer R ? R : T extends (args: any) => infer R ? R : never
g<function (type parameter) T in type g<T>
T> = (alias) namespace gWithContextimport gWithContext
gWithContext.type gWithContext.infer<T> = T extends () => (args: any) => infer R ? R : T extends (args: any) => infer R ? R : never
infer<function (type parameter) T in type g<T>
T>;
type type UserSource = { id: string; name: string;}
UserSource = { id: string
id: string; name: string
name: string };const const User: GObjectType<UserSource, unknown>
User: type g<T> = T extends () => (args: any) => infer R ? R : T extends (args: any) => infer R ? R : never
g<typeof const g: GWithContext<unknown>
g.object: <Source>(youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction?: { youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction: true;}) => <Fields extends { [Key in keyof Fields]: GField<...>; } & InterfaceFieldsToOutputFields<...>, const Interfaces extends readonly GInterfaceType<...>[] = []>(config: { ...;} & Omit<...>) => GObjectType<...>
object<type UserSource = { id: string; name: string;}
UserSource>> = const g: GWithContext<unknown>
g.object: <UserSource>(youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction?: { youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction: true;}) => <Fields, Interfaces>(config: { ...;} & Omit<...>) => GObjectType<...>
object<type UserSource = { id: string; name: string;}
UserSource>()({ name: string
name: "User", fields: { id: GField<UserSource, any, GNonNull<GScalarType<string, string>>, ImpliedResolver<any, GNonNull<GScalarType<string, string>>, unknown>, unknown>; name: GField<...>; friends: GField<...>;} | (() => { id: GField<UserSource, any, GNonNull<GScalarType<string, string>>, ImpliedResolver<any, GNonNull<GScalarType<string, string>>, unknown>, unknown>; name: GField<...>; friends: GField<...>;})
fields: () => ({ id: GField<UserSource, any, GNonNull<GScalarType<string, string>>, ImpliedResolver<any, GNonNull<GScalarType<string, string>>, unknown>, unknown>
id: const g: GWithContext<unknown>
g.field: <UserSource, GNonNull<GScalarType<string, string>>, unknown, any>(field: FieldFuncArgs<UserSource, any, GNonNull<GScalarType<string, string>>, unknown> & { ...;}) => GField<...>
field({ type: GNonNull<GScalarType<string, string>>
type: const g: GWithContext<unknown>
g.nonNull: <GScalarType<string, string>>(of: GScalarType<string, string>) => GNonNull<GScalarType<string, string>>
nonNull(const g: GWithContext<unknown>
g.type ID: GScalarType<string, string>
ID) }), name: GField<UserSource, any, GNonNull<GScalarType<string, string>>, ImpliedResolver<any, GNonNull<GScalarType<string, string>>, unknown>, unknown>
name: const g: GWithContext<unknown>
g.field: <UserSource, GNonNull<GScalarType<string, string>>, unknown, any>(field: FieldFuncArgs<UserSource, any, GNonNull<GScalarType<string, string>>, unknown> & { ...;}) => GField<...>
field({ type: GNonNull<GScalarType<string, string>>
type: const g: GWithContext<unknown>
g.nonNull: <GScalarType<string, string>>(of: GScalarType<string, string>) => GNonNull<GScalarType<string, string>>
nonNull(const g: GWithContext<unknown>
g.type String: GScalarType<string, string>
String) }), friends: GField<UserSource, any, GList<GObjectType<UserSource, unknown>>, unknown, unknown>
friends: const g: GWithContext<unknown>
g.field: <UserSource, GList<GObjectType<UserSource, unknown>>, () => never[], any>(field: FieldFuncArgs<UserSource, any, GList<GObjectType<UserSource, unknown>>, unknown> & { ...;}) => GField<...>
field({ type: GList<GObjectType<UserSource, unknown>>
type: const g: GWithContext<unknown>
g.list: <GObjectType<UserSource, unknown>>(of: GObjectType<UserSource, unknown>) => GList<GObjectType<UserSource, unknown>>
list(const User: GObjectType<UserSource, unknown>
User), resolve: ((source: UserSource, args: {}, context: unknown, info: GraphQLResolveInfo) => InferValueFromOutputType<GList<GObjectType<UserSource, unknown>>>) & (() => never[])
resolve: () => [], }), }),});type User { id: ID! name: String! friends: [User]}Alternative Syntax
The g type and g.object function is a shorthand for using GObjectType. You can also use GObjectType directly, though it does mean importing the extra type and instead of only providing the source type, you also need to provide the context type whereas with g<typeof g.object<UserSource>>, the context type is inferred from the gWithContext call.
import { function gWithContext<Context>(): GWithContext<Context>
gWithContext, class GObjectType<Source, Context>
GObjectType } from "@graphql-ts/schema";type type Context = {}
Context = {};const const g: GWithContext<Context>
g = gWithContext<Context>(): GWithContext<Context>
gWithContext<type Context = {}
Context>();type type g<T> = T extends () => (args: any) => infer R ? R : T extends (args: any) => infer R ? R : never
g<function (type parameter) T in type g<T>
T> = (alias) namespace gWithContextimport gWithContext
gWithContext.type gWithContext.infer<T> = T extends () => (args: any) => infer R ? R : T extends (args: any) => infer R ? R : never
infer<function (type parameter) T in type g<T>
T>;type type UserSource = { id: string; name: string;}
UserSource = { id: string
id: string; name: string
name: string;};
const const User: GObjectType<UserSource, Context>
User: class GObjectType<Source, Context>
GObjectType<type UserSource = { id: string; name: string;}
UserSource, type Context = {}
Context> = const g: GWithContext<Context>
g.object: <UserSource>(youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction?: { youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction: true;}) => <Fields, Interfaces>(config: { ...;} & Omit<...>) => GObjectType<...>
object<type UserSource = { id: string; name: string;}
UserSource>()({ name: string
name: "User", fields: { id: GField<UserSource, any, GNonNull<GScalarType<string, string>>, ImpliedResolver<any, GNonNull<GScalarType<string, string>>, Context>, Context>; name: GField<...>; friends: GField<...>;} | (() => { id: GField<UserSource, any, GNonNull<GScalarType<string, string>>, ImpliedResolver<any, GNonNull<GScalarType<string, string>>, Context>, Context>; name: GField<...>; friends: GField<...>;})
fields: () => ({ id: GField<UserSource, any, GNonNull<GScalarType<string, string>>, ImpliedResolver<any, GNonNull<GScalarType<string, string>>, Context>, Context>
id: const g: GWithContext<Context>
g.field: <UserSource, GNonNull<GScalarType<string, string>>, unknown, any>(field: FieldFuncArgs<UserSource, any, GNonNull<GScalarType<string, string>>, Context> & { ...;}) => GField<...>
field({ type: GNonNull<GScalarType<string, string>>
type: const g: GWithContext<Context>
g.nonNull: <GScalarType<string, string>>(of: GScalarType<string, string>) => GNonNull<GScalarType<string, string>>
nonNull(const g: GWithContext<Context>
g.type ID: GScalarType<string, string>
ID) }), name: GField<UserSource, any, GNonNull<GScalarType<string, string>>, ImpliedResolver<any, GNonNull<GScalarType<string, string>>, Context>, Context>
name: const g: GWithContext<Context>
g.field: <UserSource, GNonNull<GScalarType<string, string>>, unknown, any>(field: FieldFuncArgs<UserSource, any, GNonNull<GScalarType<string, string>>, Context> & { ...;}) => GField<...>
field({ type: GNonNull<GScalarType<string, string>>
type: const g: GWithContext<Context>
g.nonNull: <GScalarType<string, string>>(of: GScalarType<string, string>) => GNonNull<GScalarType<string, string>>
nonNull(const g: GWithContext<Context>
g.type String: GScalarType<string, string>
String) }), friends: GField<UserSource, any, GList<GObjectType<UserSource, Context>>, unknown, Context>
friends: const g: GWithContext<Context>
g.field: <UserSource, GList<GObjectType<UserSource, Context>>, () => never[], any>(field: FieldFuncArgs<UserSource, any, GList<GObjectType<UserSource, Context>>, Context> & { ...;}) => GField<...>
field({ type: GList<GObjectType<UserSource, Context>>
type: const g: GWithContext<Context>
g.list: <GObjectType<UserSource, Context>>(of: GObjectType<UserSource, Context>) => GList<GObjectType<UserSource, Context>>
list(const User: GObjectType<UserSource, Context>
User), resolve: ((source: UserSource, args: {}, context: Context, info: GraphQLResolveInfo) => InferValueFromOutputType<GList<GObjectType<UserSource, Context>>>) & (() => never[])
resolve: () => [], }), }),});type User { id: ID! name: String! friends: [User]}