Interfaces & Unions
Interfaces and unions are GraphQL's abstract types. An interface defines a set of fields that a concrete Object type (or another interface) must include to implement it. A union has no fields of its own; it only lists which Object types a field may return.
Baeta supports both directly in your .gql files and infers __typename requirements automatically.
See the GraphQL spec for the underlying semantics.
Interfaces
Defining an interface
src/modules/comic/comic.gql
interface Readable {
id: ID!
pages: Int!
}
type Comic implements Readable {
id: ID!
title: String!
year: Int!
artist: String!
pages: Int!
}
type Book implements Readable {
id: ID!
title: String!
year: Int!
author: String!
pages: Int!
}
Unions
Defining a union
src/modules/media/media.gql
type Movie {
id: ID!
title: String!
year: Int!
}
type TVShow {
id: ID!
title: String!
year: Int!
seasons: Int!
}
union Media = Movie | TVShow | Book
type Query {
media: [Media!]!
}
Extending unions
Other modules can add new members to a union via extend:
extend union Media = Comic
Type resolution
Resolvers that return a union or interface must include __typename on every returned value. The generated types enforce this: omit __typename and the resolver fails to typecheck, so you never need a custom resolveType.
Resolvers
Each entry below carries its own __typename:
const mediaQuery = Query.media.resolve(() => {
return [
{
__typename: "Book" as const,
id: "1",
title: "The Book",
author: "Jon Doe",
year: 2021,
pages: 100,
},
{
__typename: "Movie" as const,
id: "2",
title: "The Movie",
year: 2022,
},
{
__typename: "TVShow" as const,
id: "3",
title: "The TV Show",
year: 2023,
seasons: 1,
},
{
__typename: "Movie" as const,
id: "4",
title: "Another Movie",
year: 2023,
},
];
});