Implementing field resolvers for union types in Type-GraphQL aims to handle data for different members of the union type and return the correct type instance. Union types are a valuable feature in GraphQL that allow fields to have multiple possible types.
First, we need to define the union type. Suppose we have two types: Book and Movie. Both types share the commonality of being media types, but they also have their own unique fields.
typescriptimport { ObjectType, Field, ID, createUnionType } from "type-graphql"; @ObjectType() class Book { @Field(type => ID) id: string; @Field() title: string; @Field() author: string; } @ObjectType() class Movie { @Field(type => ID) id: string; @Field() title: string; @Field() director: string; } const MediaUnion = createUnionType({ name: "Media", // Set the name for the union types: () => [Book, Movie] as const, // Define the types in the union resolveType: value => { if ("author" in value) { return Book; // If 'author' field exists, consider it as Book type } if ("director" in value) { return Movie; // If 'director' field exists, consider it as Movie type } return undefined; // If no match, return undefined } });
Next, we need to create a resolver for this union type:
typescriptimport { Resolver, Query, FieldResolver, Root } from "type-graphql"; @Resolver(of => MediaUnion) export class MediaResolver { private books: Book[] = [ { id: "1", title: "1984", author: "George Orwell" }, { id: "2", title: "Brave New World", author: "Aldous Huxley" } ]; private movies: Movie[] = [ { id: "3", title: "Inception", director: "Christopher Nolan" }, { id: "4", title: "Interstellar", director: "Christopher Nolan" } ]; @Query(returns => [MediaUnion]) async getAllMedia(): Promise<Array<typeof MediaUnion>> { return [...this.books, ...this.movies]; // Merge all media type data } @FieldResolver() __resolveType(obj: any) { if (obj.author) { return 'Book'; } if (obj.director) { return 'Movie'; } return null; // If no match, return null } }
In this example, we create the MediaUnion union type, which can be either Book or Movie type. In the MediaResolver resolver, we determine the specific type by checking for the presence of certain fields (e.g., author or director). The __resolveType method is automatically invoked by TypeGraphQL to determine the specific type of the union at runtime. This enables GraphQL to correctly return different types and query fields appropriately on the client side.