Defining interfaces works exactly like defining Objects, using Interfaces
key in
SchemaTypes object for the builder, and interfaceRef
rather than objectRef
.
Lets update our Giraffe class a bit to make it work well for interfaces:
export class Animal {
diet: Diet;
constructor(diet: Diet) {
this.diet = diet;
}
}
export class Giraffe extends Animal {
name: string;
birthday: Date;
heightInMeters: number;
constructor(name: string, birthday: Date, heightInMeters: number) {
super(Diet.HERBIVOROUS);
this.name = name;
this.birthday = birthday;
this.heightInMeters = heightInMeters;
}
}
export enum Diet {
HERBIVOROUS,
CARNIVOROUS,
OMNIVORIOUS,
}
Again, using classes is completely optional. The only requirement for interfaces is that the the type used for defining objects must be a superset of the the types of any interfaces they implement.
Now that we have our classes set up we can define the interface type. and add a enum definitions for our diet field:
builder.interfaceType(Animal, {
name: 'AnimalFromClass',
fields: (t) => ({
diet: t.expose('diet', {
type: Diet,
}),
}),
});
builder.enumType(Diet, {
name: 'Diet',
});
builder.objectType(Giraffe, {
name: 'Giraffe',
interfaces: [Animal],
isTypeOf: (value) => value instanceof Giraffe,
fields: (t) => ({
name: t.exposeString('name', {}),
}),
});
There are 2 new properties here: interfaces
and isTypeOf
.
Interfaces is an array of interfaces that the object type implements, and isTypeOf
is a function
that is run whenever we have an object of the interface type and we want to see if it's actually an
instance of our object type.
Using interfaces as return types for fields works just like objects:
builder.queryFields((t) => ({
animal: t.field({
type: 'Animal',
resolve: () => new Giraffe('James', new Date(Date.UTC(2012, 11, 12)), 5.2),
}),
}));
We can query interface fields like diet on any field that returns a giraffe:
query {
giraffe {
name
diet
}
}
or we can query a field that returns an interface and select different fields depending on the concrete type:
query {
animal {
diet
... on Giraffe {
name
}
}
}