What is a union type in GraphQL and when should you use it?
Learn what a GraphQL union type is, how it differs from interfaces, how __resolveType works, and when to use unions for search and errors-as-data.
Expected Interview Answer
A GraphQL union type is a type that represents a value which could be one of several distinct object types, but unlike an interface those member types do not need to share any common fields.
You declare a union with `union SearchResult = Book | Author | Store`, and a field returning it can resolve to any one member per result. Because the members share nothing, clients must use inline fragments (`... on Book { title }`) to select fields, and the server must implement `__resolveType` so GraphQL knows which concrete type each value is. Unions shine for heterogeneous results such as search, activity feeds, or typed error/success responses.
- Models heterogeneous results in a single field
- No forced shared fields, unlike interfaces
- Type-safe discrimination via __resolveType
- Enables the errors-as-data pattern for mutations
- Clients select fields explicitly per member type
AI Mentor Explanation
A union type is like the many ways a batter can be dismissed on the scorecard: bowled, caught, run out, or LBW. Each dismissal is a completely different event with its own details, yet they all fill the single 'how out' slot. The scorer must first identify which kind it was before recording the right specifics, exactly as a resolver identifies the concrete member type.
Step-by-Step Explanation
Step 1
Declare the union
Define `union SearchResult = Book | Author | Store` in the schema listing every object type it can be.
Step 2
Return it from a field
Add a field like `search(term: String!): [SearchResult!]!` whose resolver can yield any member type.
Step 3
Implement __resolveType
On the union, provide a resolver that inspects each value and returns the concrete type name so GraphQL routes it correctly.
Step 4
Query with inline fragments
Clients write `... on Book { title }` blocks per member, optionally with `__typename` to branch in the UI.
Step 5
Handle every member client-side
Switch on `__typename` so new union members are surfaced rather than silently ignored.
What Interviewer Expects
- Clear difference between unions and interfaces
- Knowledge that members need no shared fields
- Understanding of __resolveType on the server
- Inline fragment syntax on the client
- A real use case such as search or errors-as-data
Common Mistakes
- Confusing a union with an interface that requires shared fields
- Forgetting to implement __resolveType, causing runtime errors
- Trying to select fields directly without inline fragments
- Using a union when the types genuinely share a common contract
- Not requesting __typename, making client branching impossible
Best Answer (HR Friendly)
“A union type lets one field return any one of several completely different kinds of results, like a search box that can return books, authors, or shops. It is useful when the possible answers do not share the same details, and the app just checks which kind it got before showing the right information.”
Code Example
union SearchResult = Book | Author | Store
type Book { title: String!, isbn: String! }
type Author { name: String!, bookCount: Int! }
type Store { name: String!, city: String! }
type Query {
search(term: String!): [SearchResult!]!
}
# Client query
query {
search(term: "graphql") {
__typename
... on Book { title isbn }
... on Author { name bookCount }
... on Store { name city }
}
}const resolvers = {
SearchResult: {
__resolveType(obj) {
if (obj.isbn) return 'Book'
if (obj.bookCount !== undefined) return 'Author'
if (obj.city) return 'Store'
return null
},
},
}Follow-up Questions
- How does a union differ from an interface in GraphQL?
- How would you model mutation errors using a union?
- What happens if __resolveType returns null or an unknown type?
- Can a union member itself be an interface implementation?
- How do you keep clients robust when new union members are added?
MCQ Practice
1. What must union member types have in common?
Union members need not share any fields, which is the key distinction from interfaces.
2. How does the server tell GraphQL which concrete type a union value is?
The server implements __resolveType on the union to return the concrete type name for each value.
3. How does a client select fields on a union?
Because members differ, clients use inline fragments to select fields per concrete member type.
Flash Cards
What is a GraphQL union type? — A type whose value can be one of several object types that share no common fields.
Union vs interface? — Interfaces require shared fields; unions require none and just group distinct types.
How does the server discriminate members? — By implementing __resolveType, which returns the concrete type name for each value.
How do clients select union fields? — With inline fragments such as `... on Book { title }`, usually plus __typename.
A classic union use case? — Search results or errors-as-data mutation responses where outcomes are heterogeneous.