Skip to main content
Version: Next (2.x)

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:

src/modules/types.ts
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;