Union types are defined with a list of object types:
const builder = new SchemaBuilder<{Objects: {GiraffeStringFact: { factKind: 'string'; fact: string };GiraffeNumericFact: { factKind: 'number'; fact: string; value: number };};}>({});​builder.objectType('GiraffeStringFact', {fields: (t) => ({fact: t.exposeString('fact', {}),}),});​const GiraffeNumericFact = builder.objectType('GiraffeNumericFact', {fields: (t) => ({fact: t.exposeString('fact', {}),value: t.exposeFloat('value', {}),}),});​const GiraffeFact = builder.unionType('GiraffeFact', {types: ['GiraffeStringFact', GiraffeNumericFact],resolveType: (fact) => {switch (fact.factKind) {case 'number':return GiraffeNumericFact;case 'string':return 'GiraffeStringFact';}},});
The types
array can either contain Object type names defined in TypeInfo, or and Object Ref
created by object type. builder.objectType
, builder.objectRef
or other method, or a class that was used to implement an object type.
The resolveType
function will be called with each item returned by a field that returns the unionType, and is used to determine which concrete the value corresponds to. It is usually good to have a shared property you can use to differentiate your union members.
builder.queryField('giraffeFacts', (t) =>t.field({type: [GiraffeFact],resolve: () => {const fact1 = {factKind: 'string',fact:'A giraffe’s spots are much like human fingerprints. No two individual giraffes have exactly the same pattern',} as const;​const fact2 = {factKind: 'number',fact: 'Top speed (MPH)',value: 35,} as const;​return [fact1, fact2];},}),);