Custom Types
src/modules/types.ts is the single place to override the TypeScript types Baeta hands to your resolvers: source types per GraphQL type, scalar mappings, the context shape, and the info type.
The types file
Generated shape:
import type { GraphQLResolveInfo } from "graphql";
import type { BaseObjectTypes, BaseScalars } from "../__generated__/utility.ts";
import type { Context } from "../types/context.ts";
export interface Scalars extends BaseScalars {}
export interface ObjectTypes extends BaseObjectTypes {}
export type Ctx = Context;
export type Info = GraphQLResolveInfo;
Each interface covers a different slice of type safety.
Object types
ObjectTypes overrides the source type for any GraphQL object type. By default, the source matches the GraphQL type itself; override it when your data layer returns a different shape.
Example: Prisma models
A Prisma model usually has fields the GraphQL type doesn't expose (and vice versa). Tell Baeta the source is the Prisma model:
import type { BaseObjectTypes, BaseScalars } from "../__generated__/utility.ts";
import type { User, UserPhoto } from "../lib/db/prisma.ts";
import type { Context } from "../types/context.ts";
export interface ObjectTypes extends BaseObjectTypes {
User: User; // Resolvers for User fields will receive Prisma's User as source
UserPhoto: UserPhoto;
}
In resolvers, source is now typed as the Prisma model:
const { User } = UserModule;
// source is typed as Prisma's User model, not the GraphQL User type
const userResolver = User.$fields({
id: User.id.key("id"),
email: User.email.key("email"),
// Compute GraphQL fields from the Prisma model
name: User.name.map(({ source }) => `${source.firstName} ${source.lastName}`),
photos: User.photos.map(async ({ source }) => {
return db.photo.findMany({ where: { userId: source.id } });
}),
});
Scalars
Scalars maps custom GraphQL scalars to TypeScript types. See the Scalars guide for the full setup.
export interface Scalars extends BaseScalars {
DateTime: Date;
UUID: `${string}-${string}-${string}-${string}-${string}`;
}
Context
Ctx is the context type seen by every resolver and middleware. See the Context guide.
import type { Context } from "../types/context.ts";
export type Ctx = Context;
Info
Info is the resolver info type. It defaults to GraphQLResolveInfo; override it if you use a library that extends it.
import type { GraphQLResolveInfo } from "graphql";
export type Info = GraphQLResolveInfo;