@graphql-ts/schema

Search for an npm package
    "@graphql-ts/schema"

@graphql-ts/schema

@graphql-ts/schema is a thin wrapper around GraphQL.js providing type-safety for constructing GraphQL Schemas while avoiding type-generation, declaration merging and decorators.

more
less
import { gWithContext } from "@graphql-ts/schema";
import { GraphQLSchema, graphql } from "graphql";
type Context = {
loadPerson: (id: string) => Person | undefined;
loadFriends: (id: string) => Person[];
};
const g = gWithContext<Context>();
type g<T> = gWithContext.infer<T>;
type Person = {
id: string;
name: string;
};
const Person: g<typeof g.object<Person>> = g.object<Person>()({
name: "Person",
fields: () => ({
id: g.field({ type: g.nonNull(g.ID) }),
name: g.field({ type: g.nonNull(g.String) }),
friends: g.field({
type: g.list(g.nonNull(Person)),
resolve(source, _, context) {
return context.loadFriends(source.id);
},
}),
}),
});
const Query = g.object()({
name: "Query",
fields: {
person: g.field({
type: Person,
args: {
id: g.arg({ type: g.nonNull(g.ID) }),
},
resolve(_, args, context) {
return context.loadPerson(args.id);
},
}),
},
});
const schema = new GraphQLSchema({
query: Query,
});
{
const people = new Map<string, Person>([
["1", { id: "1", name: "Alice" }],
["2", { id: "2", name: "Bob" }],
]);
const friends = new Map<string, string[]>([
["1", ["2"]],
["2", ["1"]],
]);
const contextValue: Context = {
loadPerson: (id) => people.get(id),
loadFriends: (id) => {
return (friends.get(id) ?? [])
.map((id) => people.get(id))
.filter((person) => person !== undefined) as Person[];
},
};
graphql({
source: `
query {
person(id: "1") {
id
name
friends {
id
name
}
}
}
`,
schema,
contextValue,
}).then((result) => {
console.log(result);
});
}
module "@graphql-ts/schema" {

The gWithContext function accepts a Context type parameter which binds the returned functions so they can be used to compose GraphQL types into a GraphQL schema.

more
less

A simple schema with only a query type looks like this:

import { gWithContext } from "@graphql-ts/schema";
import { GraphQLSchema, graphql } from "graphql";
type Context = {};
const g = gWithContext<Context>();
type g<T> = gWithContext.infer<T>;
const Query = g.object()({
name: "Query",
fields: {
hello: g.field({
type: g.String,
resolve() {
return "Hello!";
},
}),
},
});
const schema = new GraphQLSchema({
query: Query,
});
graphql({
source: `
query {
hello
}
`,
schema,
}).then((result) => {
console.log(result);
});

You can use pass the schema to ApolloServer and other GraphQL servers.

You can also create a more advanced schema with other object types, circular types, args, and mutations. See GWithContext for what the other functions on g do.

import { gWithContext } from "@graphql-ts/schema";
import { GraphQLSchema, graphql } from "graphql";
import { deepEqual } from "node:assert";
type Context = {
todos: Map<string, TodoItem>;
};
const g = gWithContext<Context>();
type g<T> = gWithContext.infer<T>;
type TodoItem = {
id: string;
title: string;
relatedTodos: string[];
};
const Todo: g<typeof g.object<TodoItem>> = g.object<TodoItem>()({
name: "Todo",
fields: () => ({
id: g.field({ type: g.nonNull(g.ID) }),
title: g.field({ type: g.nonNull(g.String) }),
relatedTodos: g.field({
type: g.list(Todo),
resolve(source, _args, context) {
return source.relatedTodos
.map((id) => context.todos.get(id))
.filter((todo) => todo !== undefined);
},
}),
}),
});
const Query = g.object()({
name: "Query",
fields: {
todos: g.field({
type: g.list(Todo),
resolve(_source, _args, context) {
return context.todos.values();
},
}),
},
});
const Mutation = g.object()({
name: "Mutation",
fields: {
createTodo: g.field({
args: {
title: g.arg({ type: g.nonNull(g.String) }),
relatedTodos: g.arg({
type: g.nonNull(g.list(g.nonNull(g.ID))),
defaultValue: [],
}),
},
type: Todo,
resolve(_source, { title, relatedTodos }, context) {
const todo = { title, relatedTodos, id: crypto.randomUUID() };
context.todos.set(todo.id, todo);
return todo;
},
}),
},
});
const schema = new GraphQLSchema({
query: Query,
mutation: Mutation,
});
(async () => {
const contextValue: Context = { todos: new Map() };
{
const result = await graphql({
source: `
query {
todos {
title
}
}
`,
schema,
contextValue,
});
deepEqual(result, { data: { todos: [] } });
}
{
const result = await graphql({
source: `
mutation {
createTodo(title: "Try graphql-ts") {
title
}
}
`,
schema,
contextValue,
});
deepEqual(result, {
data: { createTodo: { title: "Try graphql-ts" } },
});
}
{
const result = await graphql({
source: `
query {
todos {
title
}
}
`,
schema,
contextValue,
});
deepEqual(result, {
data: { todos: [{ title: "Try graphql-ts" }] },
});
}
})();
export function gWithContext<Context>(): GWithContext<Context>
export namespace gWithContext {

The gWithContext.infer type is useful particularly when defining circular types to resolve errors from TypeScript because of the circularity.

more
less

We recommend aliasing gWithContext.infer to your g like this to make it easier to use:

import { gWithContext } from "@graphql-ts/schema";
type Context = {};
const g = gWithContext<Context>();
type g<T> = gWithContext.infer<T>;
type PersonSource = { name: string; friends: PersonSource[] };
const Person: g<typeof g.object<PersonSource>> =
g.object<PersonSource>()({
name: "Person",
fields: () => ({
name: g.field({ type: g.String }),
friends: g.field({ type: g.list(Person) }),
}),
});
export type infer<T> = T extends () => (args: any) => infer R ? R : T extends (args: any) => infer R ? R : never
Referenced by
  • gWithContext
}
export type GWithContext<Context> = {

Creates a GraphQL object type.

more
less

Note this is an output type, if you want an input object, use g.inputObject.

When calling g.object, you must provide a type parameter that is the source of the object type. The source is what you receive as the first argument of resolvers on this type and what you must return from resolvers of fields that return this type.

const Person = g.object<{ name: string }>()({
name: "Person",
fields: {
name: g.field({ type: g.String }),
},
});
// ==
graphql`
type Person {
name: String
}
`;

Writing resolvers

To do anything other than just return a field from the source type, you need to provide a resolver.

Note: TypeScript will force you to provide a resolve function if the field in the source type and the GraphQL field don't match

const Person = g.object<{ name: string }>()({
name: "Person",
fields: {
name: g.field({ type: g.String }),
excitedName: g.field({
type: g.String,
resolve(source, args, context, info) {
return `${source.name}!`;
},
}),
},
});

Circularity

GraphQL types will often contain references to themselves and to make TypeScript allow that, you need have an explicit type annotation of g<typeof g.object<Source>> along with making fields a function that returns the object.

type PersonSource = { name: string; friends: PersonSource[] };
const Person: g<typeof g.object<PersonSource>> =
g.object<PersonSource>()({
name: "Person",
fields: () => ({
name: g.field({ type: g.String }),
friends: g.field({ type: g.list(Person) }),
}),
});
object: <Source>(youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction?: {
youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction: true;
}) => <Fields extends {
[Key in keyof Fields]: GField<Source, any, any, Key extends keyof Source ? Source[Key] : unknown, Context>;
} & InterfaceFieldsToOutputFields<Source, Context, InterfacesToInterfaceFields<Interfaces>>, Interfaces extends readonly GInterfaceType<Source, any, Context>[] = []>(config: {
fields: Fields | (() => Fields);
interfaces?: [...Interfaces];
} & Omit<import("graphql").GraphQLObjectTypeConfig<Source, Context>, "fields" | "interfaces">) => GObjectType<Source, Context>;

Create a GraphQL union type.

more
less

A union type represents an object that could be one of a list of types. Note it is similar to an interface type except that a union doesn't imply having a common set of fields among the member types.

const A = g.object<{ __typename: "A" }>()({
name: "A",
fields: {
something: g.field({ type: g.String }),
},
});
const B = g.object<{ __typename: "B" }>()({
name: "B",
fields: {
differentThing: g.field({ type: g.String }),
},
});
const AOrB = g.union({
name: "AOrB",
types: [A, B],
});
union: <Type extends GObjectType<any, Context>>(config: Flatten<Omit<import("graphql").GraphQLUnionTypeConfig<Type extends GObjectType<infer Source, Context> ? Source : never, Context>, "types"> & {
types: readonly Type[] | (() => readonly Type[]);
}>) => GUnionType<Type extends GObjectType<infer Source, Context> ? Source : never, Context>;

Creates a GraphQL field.

more
less

These will generally be passed directly to the fields object in a g.object call.

const Something = g.object<{ thing: string }>()({
name: "Something",
fields: {
thing: g.field({ type: g.String }),
},
});
field: <Source, Type extends GOutputType<Context>, Resolve, Args extends {
[Key in keyof Args]: GArg<GInputType>;
} = {}>(field: FieldFuncArgs<Source, Args, Type, Context> & (Resolve extends {} ? {
resolve: ((source: Source, args: InferValueFromArgs<SomeTypeThatIsntARecordOfArgs extends Args ? {} : Args>, context: Context, info: import("graphql").GraphQLResolveInfo) => InferValueFromOutputType<Type>) & Resolve;
} : {
resolve?: ((source: Source, args: InferValueFromArgs<SomeTypeThatIsntARecordOfArgs extends Args ? {} : Args>, context: Context, info: import("graphql").GraphQLResolveInfo) => InferValueFromOutputType<Type>) & Resolve;
})) => GField<Source, Args, Type, Resolve extends {} ? unknown : ImpliedResolver<Args, Type, Context>, Context>;

A helper to declare fields while providing the source type a single time rather than in every resolver.

more
less
const nodeFields = g.fields<{ id: string }>()({
id: g.field({ type: g.ID }),
relatedIds: g.field({
type: g.list(g.ID),
resolve(source) {
return loadRelatedIds(source.id);
},
}),
otherRelatedIds: g.field({
type: g.list(g.ID),
resolve(source) {
return loadOtherRelatedIds(source.id);
},
}),
});
const Person = g.object<{
id: string;
name: string;
}>()({
name: "Person",
fields: {
...nodeFields,
name: g.field({ type: g.String }),
},
});
fields: <Source>(youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction?: {
youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction: true;
}) => <Fields extends Record<string, GField<Source, any, GOutputType<Context>, any, Context>> & {
[Key in keyof Source]?: GField<Source, any, GOutputType<Context>, Source[Key], Context>;
}>(fields: Fields) => Fields;

Creates a GraphQL interface field.

more
less

These will generally be passed directly to the fields object in a call. Interfaces fields are similar to regular fields except that they don't define how the field is resolved.

const Entity = g.interface()({
name: "Entity",
fields: {
name: g.interfaceField({ type: g.String }),
},
});

Note that regular fields are assignable to interface fields but the opposite is not true. This means that you can use a regular field in an interface type.

interfaceField: <Args extends {
[Key in keyof Args]: GArg<GInputType>;
}, Type extends GOutputType<Context>>(field: GInterfaceField<Args, Type, Context>) => GInterfaceField<Args, Type, Context>;

Creates a GraphQL interface type that can be implemented by other GraphQL object and interface types.

more
less
const Entity = g.interface()({
name: "Entity",
fields: {
name: g.interfaceField({ type: g.String }),
},
});
type PersonSource = { __typename: "Person"; name: string };
const Person = g.object<PersonSource>()({
name: "Person",
interfaces: [Entity],
fields: {
name: g.field({ type: g.String }),
},
});
type OrganisationSource = {
__typename: "Organisation";
name: string;
};
const Organisation = g.object<OrganisationSource>()({
name: "Organisation",
interfaces: [Entity],
fields: {
name: g.field({ type: g.String }),
},
});

Resolving Types

When using GraphQL interface and union types, there needs to a way to determine which concrete object type has been returned from a resolver. With graphql-js and @graphql-ts/schema, this is done with isTypeOf on object types and resolveType on interface and union types. Note @graphql-ts/schema does not aim to strictly type the implementation of resolveType and isTypeOf. If you don't provide resolveType or isTypeOf, a __typename property on the source type will be used, if that fails, an error will be thrown at runtime.

Fields vs Interface Fields

You might have noticed that g.interfaceField was used instead of g.field for the fields on the interfaces. This is because interfaces aren't defining implementation of fields which means that fields on an interface don't need define resolvers.

Sharing field implementations

Even though interfaces don't contain field implementations, you may still want to share field implementations between interface implementations. You can use g.fields to do that. See g.fields for more information about why you should use g.fields instead of just defining an object the fields and spreading that.

const nodeFields = g.fields<{ id: string }>({
id: g.field({ type: g.ID }),
});
const Node = g.field({
name: "Node",
fields: nodeFields,
});
const Person = g.object<{
__typename: "Person";
id: string;
name: string;
}>()({
name: "Person",
interfaces: [Node],
fields: {
...nodeFields,
name: g.field({ type: g.String }),
},
});
interface: <Source>(youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction?: {
youOnlyNeedToPassATypeParameterToThisFunctionYouPassTheActualRuntimeArgsOnTheResultOfThisFunction: true;
}) => <Fields extends {
[Key in keyof Fields]: GInterfaceField<any, GOutputType<Context>, Context>;
} & InterfacesToInterfaceFields<Interfaces>, Interfaces extends readonly GInterfaceType<Source, any, Context>[] = []>(config: GInterfaceTypeConfig<Source, Fields, Interfaces, Context>) => GInterfaceType<Source, Fields, Context>;

A shorthand to easily create enum values to pass to .

more
less

If you need to set a description or deprecationReason for an enum variant, you should pass values directly to g.enum without using g.enumValues.

const MyEnum = g.enum({
name: "MyEnum",
values: g.enumValues(["a", "b"]),
});
const values = g.enumValues(["a", "b"]);
assertDeepEqual(values, {
a: { value: "a" },
b: { value: "b" },
});
enumValues: <Values extends readonly string[]>(values: readonly [...Values]) => {
[Key in Values[number]]: GEnumValueConfig<Key>;
};

Creates an enum type with a number of enum values.

more
less
const MyEnum = g.enum({
name: "MyEnum",
values: g.enumValues(["a", "b"]),
});
// ==
graphql`
enum MyEnum {
a
b
}
`;
const MyEnum = g.enum({
name: "MyEnum",
description: "My enum does things",
values: {
something: {
description: "something something",
value: "something",
},
thing: {
description: "thing thing",
deprecationReason: "something should be used instead of thing",
value: "thing",
},
},
});
// ==
graphql`
"""
My enum does things
"""
enum MyEnum {
"""
something something
"""
something
"""
thing thing
"""
thing
@ — \deprecated(reason: "something should be used instead of thing")
}
`;)
enum: <Values extends Record<string, unknown>>(config: GEnumTypeConfig<Values>) => GEnumType<Values>;

Creates a GraphQL argument.

more
less

Args can can be used as arguments on output fields:

g.field({
type: g.String,
args: {
something: g.arg({ type: g.String }),
},
resolve(source, { something }) {
return something || somethingElse;
},
});
// ==
graphql`(something: String): String`;

Or as fields on input objects:

const Something = g.inputObject({
name: "Something",
fields: {
something: g.arg({ type: g.String }),
},
});
// ==
graphql`
input Something {
something: String
}
`;
arg: <Type extends GInputType, DefaultValue extends InferValueFromInputType<Type> | undefined = undefined>(arg: Flatten<{
type: Type;
} & Omit<import("graphql").GraphQLInputFieldConfig & import("graphql").GraphQLArgumentConfig, "type" | "defaultValue">> & (undefined extends DefaultValue ? {
defaultValue?: DefaultValue;
} : {
defaultValue: DefaultValue;
})) => GArg<Type, DefaultValue extends undefined ? false : true>;

Creates an input object type

more
less
const Something = g.inputObject({
name: "Something",
fields: {
something: g.arg({ type: g.String }),
},
});
// ==
graphql`
input Something {
something: String
}
`;

Handling circular objects

Circular input objects require explicitly specifying the fields on the object in the type because of TypeScript's limits with circularity.

import { GInputObjectType } from "@graphql-ts/schema";
type SomethingInputType = GInputObjectType<{
something: g<typeof g.arg<SomethingInputType>>;
}>;
const Something: SomethingInputType = g.inputObject({
name: "Something",
fields: () => ({
something: g.arg({ type: Something }),
}),
});

You can specify all of your non-circular fields outside of the fields object and then use typeof to get the type to avoid writing the non-circular fields as types again.

import { GInputObjectType } from "@graphql-ts/schema";
const nonCircularFields = {
thing: g.arg({ type: g.String }),
};
type SomethingInputType = GInputObjectType<
typeof nonCircularFields & {
something: g<typeof g.arg<SomethingInputType>>;
}
>;
const Something: SomethingInputType = g.inputObject({
name: "Something",
fields: () => ({
...nonCircularFields,
something: g.arg({ type: Something }),
}),
});
inputObject: <Fields extends {
[key: string]: IsOneOf extends true ? GArg<GNullableInputType, false> : GArg<GInputType>;
}, IsOneOf extends boolean = false>(config: GInputObjectTypeConfig<Fields, IsOneOf>) => GInputObjectType<Fields, IsOneOf>;

Wraps any GraphQL type in a list type.

more
less
const stringListType = g.list(g.String);
// ==
graphql`[String]`;

When used as an input type, you will recieve an array of the inner type.

g.field({
type: g.String,
args: { thing: g.arg({ type: g.list(g.String) }) },
resolve(source, { thing }) {
const theThing: undefined | null | Array<string | null> = thing;
return "";
},
});

When used as an output type, you can return an iterable of the inner type that also matches typeof val === 'object' so for example, you'll probably return an Array most of the time but you could also return a Set you couldn't return a string though, even though a string is an iterable, it doesn't match typeof val === 'object'.

g.field({
type: g.list(g.String),
resolve() {
return [""];
},
});
g.field({
type: g.list(g.String),
resolve() {
return new Set([""]);
},
});
g.field({
type: g.list(g.String),
resolve() {
// this will not be allowed
return "some things";
},
});
list: <Of extends GType<any>>(of: Of) => GList<Of>;

Wraps a nullable type with a non-nullable type.

more
less

Types in GraphQL are always nullable by default so if you want to enforce that a type must always be there, you can use the non-null type.

const nonNullableString = g.nonNull(g.String);
// ==
graphql`String!`;

When using a non-null type as an input type, your resolver will never recieve null and consumers of your GraphQL API must provide a value for it unless you provide a default value.

g.field({
args: {
someNonNullAndRequiredArg: g.arg({
type: g.nonNull(g.String),
}),
someNonNullButOptionalArg: g.arg({
type: g.nonNull(g.String),
defaultValue: "some default",
}),
},
type: g.String,
resolve(source, args) {
// both of these will always be a string
args.someNonNullAndRequiredArg;
args.someNonNullButOptionalArg;
return "";
},
});
// ==
graphql`
fieldName(
someNonNullAndRequiredArg: String!
someNonNullButOptionalArg: String! = "some default"
): String
`;

When using a non-null type as an output type, your resolver must never return null. If you do return null(which unless you do type-casting/ts-ignore/etc. @graphql-ts/schema will not let you do) graphql-js will return an error to consumers of your GraphQL API.

Non-null types should be used very carefully on output types. If you have to do a fallible operation like a network request or etc. to get the value, it probably shouldn't be non-null. If you make a field non-null and doing the fallible operation fails, consumers of your GraphQL API will be unable to see any of the other fields on the object that the non-null field was on. For example, an id on some type is a good candidate for being non-null because if you have the item, you will already have the id so getting the id will never fail but fetching a related item from a database would be fallible so even if it will never be null in the success case, you should make it nullable.

g.field({
type: g.nonNull(g.String),
resolve(source, args) {
return "something";
},
});
// ==
graphql`
fieldName: String!
`;

If you try to wrap another non-null type in a non-null type again, you will get a type error.

// Argument of type 'NonNullType<ScalarType<string>>'
// is not assignable to parameter of type 'NullableType'.
g.nonNull(g.nonNull(g.String));
nonNull: <Of extends GNullableType<any>>(of: Of) => GNonNull<Of>;

Creates a scalar type.

more
less
const BigInt = g.scalar({
name: "BigInt",
serialize(value) {
if (typeof value !== "bigint")
throw new GraphQLError(
`unexpected value provided to BigInt scalar: ${value}`
);
return value.toString();
},
parseLiteral(value) {
if (value.kind !== "StringValue")
throw new GraphQLError("BigInt only accepts values as strings");
return globalThis.BigInt(value.value);
},
parseValue(value) {
if (typeof value === "bigint") return value;
if (typeof value !== "string")
throw new GraphQLError("BigInt only accepts values as strings");
return globalThis.BigInt(value);
},
});
// for fields on output types
g.field({ type: someScalar });
// for args on output fields or fields on input types
g.arg({ type: someScalar });

Note, while graphql-js allows you to express scalar types like the ID type which accepts integers and strings as both input values and return values from resolvers which are transformed into strings before calling resolvers and returning the query respectively, the type you use should be string for ID since that is what it is transformed into. @graphql-ts/schema doesn't currently express the coercion of scalars, you should instead convert values to the canonical form yourself before returning from resolvers.

scalar: <Internal, External = Internal>(config: import("graphql").GraphQLScalarTypeConfig<Internal, External>) => GScalarType<Internal, External>;
ID: GScalarType<string>;
String: GScalarType<string>;
Float: GScalarType<number>;
Int: GScalarType<number>;
Boolean: GScalarType<boolean>;
}
Referenced by
Unexported symbols referenced here
type InterfaceFieldsToOutputFields<Source, Context, Fields extends {
[key: string]: GInterfaceField<any, any, any>;
}> = {
[Key in keyof Fields]: Fields[Key] extends GInterfaceField<infer Args, infer OutputType, any> ? GField<Source, Args, OutputType, Key extends keyof Source ? Source[Key] : unknown, Context> : never;
}
Referenced by
type InterfacesToInterfaceFields<Interfaces extends readonly GInterfaceType<any, any, any>[]> = MergeTuple<{
[Key in keyof Interfaces]: Interfaces[Key] extends GInterfaceType<any, infer Fields, any> ? Fields : never;
}, {}>
Referenced by
type Flatten<T> = {
[Key in keyof T]: T[Key];
} & {}
Referenced by
type FieldFuncArgs<Source, Args extends {
[Key in keyof Args]: GArg<GInputType>;
}, Type extends GOutputType<Context>, Context> = {
args?: Args;
type: Type;
description?: Maybe<string>;
deprecationReason?: Maybe<string>;
extensions?: Maybe<Readonly<import("graphql").GraphQLFieldExtensions<Source, Context>>>;
astNode?: Maybe<import("graphql").FieldDefinitionNode>;
}
Referenced by
type SomeTypeThatIsntARecordOfArgs = string
Referenced by
type ImpliedResolver<Args extends {
[Key in keyof Args]: GArg<GInputType>;
}, Type extends GOutputType<Context>, Context> = InferValueFromOutputType<Type> | ((args: InferValueFromArgs<Args>, context: Context, info: import("graphql").GraphQLResolveInfo) => InferValueFromOutputType<Type>)
Referenced by
type GInterfaceTypeConfig<Source, Fields extends Record<string, GInterfaceField<any, GOutputType<Context>, Context>>, Interfaces extends readonly GInterfaceType<Source, any, Context>[], Context> = Flatten<{
fields: Fields | (() => Fields);
interfaces?: [...Interfaces];
} & Omit<import("graphql").GraphQLInterfaceTypeConfig<Source, Context>, "interfaces" | "fields">>
Referenced by
type GEnumValueConfig<Value> = import("graphql").GraphQLEnumValueConfig & {
value: Value;
}
Referenced by
type GEnumTypeConfig<Values extends {
[key: string]: unknown;
}> = Flatten<{
values: {
[Name in keyof Values]: GEnumValueConfig<Values[Name]>;
};
} & Omit<import("graphql").GraphQLEnumTypeConfig, "values">>
Referenced by
type GInputObjectTypeConfig<Fields extends {
[key: string]: IsOneOf extends true ? GArg<GNullableInputType, false> : GArg<GInputType>;
}, IsOneOf extends boolean = false> = Flatten<Omit<import("graphql").GraphQLInputObjectTypeConfig, "fields"> & {
fields: Fields | (() => Fields);
isOneOf?: IsOneOf;
}> & (true extends IsOneOf ? {
isOneOf: unknown;
} : unknown)
Referenced by
type MergeTuple<T, Merged> = T extends readonly [infer U, ...infer Rest] ? MergeTuple<Rest, Merged & U> : Merged
Referenced by
type Maybe<T> = T | null | undefined
Referenced by

A GraphQL object type. This should generally be constructed with object.

more
less

Note this is an output type, if you want an input object, use GInputObjectType.

If you use the GObjectType constructor directly, all fields will need explicit resolvers so you should use g.object instead.

export class GObjectType<Source, Context> extends import("graphql").GraphQLObjectType<Source, Context> {
constructor(config: Readonly<GObjectTypeConfig<Source, Context, Record<string, GField<Source, any, any, unknown, Context>>, readonly GInterfaceType<Source, any, Context>[]>>)
}
Referenced by
Unexported symbols referenced here
type GObjectTypeConfig<Source, Context, Fields extends Record<string, GField<Source, any, any, any, Context>>, Interfaces extends readonly GInterfaceType<Source, any, Context>[]> = {
fields: Fields | (() => Fields);
interfaces?: [...Interfaces];
} & Omit<import("graphql").GraphQLObjectTypeConfig<Source, Context>, "fields" | "interfaces">
Referenced by

A GraphQL enum type. This should generally be constructed with enum.

more
less

Unlike some other constructors in this module, this constructor functions exactly the same as it's counterpart g.enum so it is safe to use directly if desired.

export class GEnumType<Values extends {
[key: string]: unknown;
}> extends import("graphql").GraphQLEnumType {
constructor(config: Readonly<GEnumTypeConfig<Values>>)
toConfig(): Omit<ReturnType<import("graphql").GraphQLEnumType["toConfig"]>, "values"> & {
values: {
[Name in keyof Values]: Partial<GEnumValueConfig<Values[Name]>>;
};
};
}
Referenced by

A GraphQL enum type. This should generally be constructed with scalar.

more
less

Unlike some other constructors in this module, this constructor functions exactly the same as it's counterpart g.scalar so it is safe to use directly if desired.

Also unlike some other types in this module, this type is exactly equivalent to the original GraphQLScalarType type from the graphql package.

export class GScalarType<Internal = unknown, External = Internal> extends import("graphql").GraphQLScalarType<Internal, External> {}
Referenced by

A GraphQL input object type. This should generally be constructed with inputObject.

more
less

Unlike some other constructors in this module, this constructor functions exactly the same as it's counterpart g.inputObject so it is safe to use directly if desired.

export class GInputObjectType<Fields extends {
[key: string]: IsOneOf extends true ? GArg<GNullableInputType, false> : GArg<GInputType>;
}, IsOneOf extends boolean = false> extends import("graphql").GraphQLInputObjectType {
constructor(config: Readonly<GInputObjectTypeConfig<Fields, IsOneOf>>)
isOneOf: IsOneOf;
getFields(): {
[K in keyof Fields]: import("graphql").GraphQLInputField & {
type: Fields[K]["type"];
defaultValue: Fields[K]["defaultValue"];
};
};
}
Referenced by

A GraphQL interface type that can be implemented by other GraphQL object and interface types. This should generally be constructed with interface.

more
less

If you use the GInterfaceType constructor directly, all fields will need explicit resolvers so you should use g.interface instead.

export class GInterfaceType<Source, Fields extends Record<string, GInterfaceField<any, GOutputType<Context>, Context>>, Context> extends import("graphql").GraphQLInterfaceType {
constructor(config: Readonly<GInterfaceTypeConfig<Source, Fields, readonly GInterfaceType<Source, {}, Context>[], Context>>)
resolveType: Maybe<import("graphql").GraphQLTypeResolver<Source, Context>>;
toConfig(): Omit<ReturnType<import("graphql").GraphQLInterfaceType["toConfig"]>, "fields"> & {
fields: Fields;
};
}
Referenced by
Unexported symbols referenced here
type Maybe<T> = T | null | undefined
Referenced by

A GraphQL union type. This should generally be constructed with union.

more
less

A union type represents an object that could be one of a list of types. Note it is similar to an GInterfaceType except that a union doesn't imply having a common set of fields among the member types.

While this constructor will work, you should generally use g.union because you will need to explicitly provide the source type parameter as TypeScript is unable to infer it correctly. Note this is only required for this constructor, this is not required when using g.union.

export class GUnionType<Source, Context> extends import("graphql").GraphQLUnionType {
constructor(config: Readonly<GUnionTypeConfig<Source extends any ? GObjectType<Source, Context> : never, Context>>)
resolveType: Maybe<import("graphql").GraphQLTypeResolver<Source, Context>>;
}
Referenced by
Unexported symbols referenced here
type GUnionTypeConfig<ObjectType extends GObjectType<any, Context>, Context> = Flatten<{
types: readonly ObjectType[] | (() => readonly ObjectType[]);
} & Omit<import("graphql").GraphQLUnionTypeConfig<ObjectType extends GObjectType<infer Source, Context> ? Source : never, Context>, "types">>
Referenced by

A GraphQL list type. This should generally be constructed with list.

more
less

Unlike some other constructors in this module, this constructor functions exactly the same as it's counterpart g.list so it is safe to use directly if desired.

Also unlike the named types in this module, the original GraphQLList type from the graphql package cannot be assigned to a variable of type GList. Though GList is assignable to GraphQLList.

For example, the following code will not compile:

const list: GList<GScalarType<string>> = new GraphQLList(GraphQLString);

But the following code will compile:

const list: GraphQLList<GraphQLScalarType<string>> = new GList(
GraphQLString
);

This is due to the lack of a discriminating property between the GraphQLNonNull and GraphQLList types.

export class GList<Of extends GType<any>> extends import("graphql").GraphQLList<Of> {
get [Symbol.toStringTag](): "GraphQLList";
}
Referenced by

A GraphQL non-null type. This should generally be constructed with nonNull.

more
less

Unlike some other constructors in this module, this constructor functions exactly the same as it's counterpart g.nonNull so it is safe to use directly if desired.

Also unlike the named types in this module, the original GraphQLNonNull type from the graphql package cannot be assigned to a variable of type GNonNull. Though GNonNull is assignable to GraphQLNonNull.

For example, the following code will not compile:

const nonNull: GNonNull<GScalarType<string>> = new GraphQLNonNull(
GraphQLString
);

But the following code will compile:

const nonNull: GraphQLNonNull<GraphQLScalarType<string>> = new GNonNull(
GraphQLString
);

This is due to the lack of a discriminating property between the GraphQLNonNull and GraphQLList types.

export class GNonNull<Of extends GNullableType<any>> extends import("graphql").GraphQLNonNull<Of> {
get [Symbol.toStringTag](): "GraphQLNonNull";
}
Referenced by

A GraphQL argument. These should be created with arg

more
less

Args can can be used as arguments on output fields:

g.field({
type: g.String,
args: {
something: g.arg({ type: g.String }),
},
resolve(source, { something }) {
return something || somethingElse;
},
});
// ==
graphql`fieldName(something: String): String`;

Or as fields on input objects:

g.inputObject({
name: "Something",
fields: {
something: g.arg({ type: g.String }),
},
});
// ==
graphql`
input Something {
something: String
}
`;

When the type of an arg is non-null, the value will always exist.

g.field({
type: g.String,
args: {
something: g.arg({ type: g.nonNull(g.String) }),
},
resolve(source, { something }) {
// `something` will always be a string
return something;
},
});
// ==
graphql`fieldName(something: String!): String`;
export type GArg<Type extends GInputType, HasDefaultValue extends boolean = boolean> = {
type: Type;
defaultValue: {
true: {} | null;
false: undefined;
}[`${HasDefaultValue}`];
description?: Maybe<string>;
deprecationReason?: Maybe<string>;
}
Referenced by

A GraphQL output field for an object type which should be created using field.

export type GField<Source, Args extends {
[Key in keyof Args]: GArg<GInputType>;
}, Type extends GOutputType<Context>, SourceAtKey, Context> = {
args?: Args;
type: Type;
resolve?: GFieldResolver<Source, Args, Type, Context>;
description?: Maybe<string>;
deprecationReason?: Maybe<string>;
extensions?: Maybe<Readonly<import("graphql").GraphQLFieldExtensions<any, Context>>>;
astNode?: Maybe<import("graphql").FieldDefinitionNode>;
__missingResolve: undefined | ((arg: SourceAtKey) => void);
}
Referenced by
export type GFieldResolver<Source, Args extends Record<string, GArg<GInputType>>, Type extends GOutputType<Context>, Context> = (source: Source, args: InferValueFromArgs<Args>, context: Context, info: import("graphql").GraphQLResolveInfo) => InferValueFromOutputType<Type>
Referenced by
export type GInterfaceField<Args extends Record<string, GArg<GInputType>>, Type extends GOutputType<Context>, Context> = {
description?: Maybe<string>;
type: Type;
args?: Args;
deprecationReason?: Maybe<string>;
extensions?: Maybe<Readonly<import("graphql").GraphQLFieldExtensions<any, Context>>>;
astNode?: Maybe<import("graphql").FieldDefinitionNode>;
}
Referenced by
export type GNullableOutputType<Context> = GScalarType | GObjectType<any, Context> | GInterfaceType<any, any, Context> | GUnionType<any, Context> | GEnumType<Record<string, unknown>> | GList<GOutputType<Context>>
Referenced by
export type GNullableType<Context> = GNullableOutputType<Context> | GNullableInputType
Referenced by
export type GType<Context> = GOutputType<Context> | GInputType
Referenced by
export type InferValueFromOutputType<Type extends GOutputType<any>> = MaybePromise<Type extends GNonNull<infer Value extends GNullableOutputType<any>> ? InferValueFromOutputTypeWithoutAddingNull<Value> : InferValueFromOutputTypeWithoutAddingNull<Type> | null | undefined>
Referenced by
Unexported symbols referenced here
type MaybePromise<T> = Promise<T> | T
Referenced by
type InferValueFromOutputTypeWithoutAddingNull<Type extends GOutputType<any>> = Type extends import("graphql").GraphQLScalarType<infer Value> ? Value : Type extends import("graphql").GraphQLEnumType ? Type extends GEnumType<infer Values> ? Values[keyof Values] : never : Type extends GList<infer Value extends GOutputType<any>> ? object & Iterable<InferValueFromOutputType<Value>> : Type extends import("graphql").GraphQLObjectType<infer Source, any> ? Source : Type extends import("graphql").GraphQLUnionType | import("graphql").GraphQLInterfaceType ? Type extends GUnionType<infer Source, any> | GInterfaceType<infer Source, any, any> ? Source : unknown : never
Referenced by
export type InferValueFromArg<Arg extends GArg<GInputType>> = Arg extends unknown ? InferValueFromInputType<Arg["type"]> | AddUndefined<Arg["type"], Arg["defaultValue"]> : never
Referenced by
Unexported symbols referenced here
type AddUndefined<TInputType extends GInputType, DefaultValue> = TInputType extends GNonNull<any> ? never : DefaultValue & undefined
Referenced by
export type InferValueFromArgs<Args extends Record<string, GArg<GInputType>>> = {
readonly [Key in keyof Args]: InferValueFromArg<Args[Key]>;
} & {}
Referenced by
export type InferValueFromInputType<Type extends GInputType> = Type extends GNonNull<infer Value extends GNullableInputType> ? InferValueFromNullableInputType<Value> : InferValueFromNullableInputType<Type> | null
Referenced by
Unexported symbols referenced here
type InferValueFromNullableInputType<Type extends GInputType> = Type extends import("graphql").GraphQLScalarType<infer Value, any> ? Value : Type extends import("graphql").GraphQLEnumType ? Type extends GEnumType<infer Values> ? Values[keyof Values] : unknown : Type extends GList<infer Value extends GInputType> ? InferValueFromInputType<Value>[] : Type extends import("graphql").GraphQLInputObjectType ? Type extends GInputObjectType<infer Fields, infer IsOneOf> ? IsOneOf extends true ? InferValueForOneOf<Fields> : InferValueFromArgs<Fields> : Record<string, unknown> : never
Referenced by
type InferValueForOneOf<T extends {
[key: string]: {
type: GInputType;
};
}, Key extends keyof T = keyof T> = Flatten<Key extends unknown ? {
readonly [K in Key]: InferValueFromNullableInputType<T[K]["type"]>;
} & {
readonly [K in Exclude<keyof T, Key>]?: never;
} : never>
Referenced by
}