For each collection that has relation fields, pbkit generates an XxxExpand
type: a union of every valid expand path, and an XxxRelations map that drives
the typed .expand shape on read results.
For the concept behind how these paths are computed, see Relations and expand paths.
Generated type
Section titled “Generated type”Given an articles collection with author (relation to users) and
categories (relation to categories), and a comments collection with
article and author relations:
// Direct relationsexport type ArticlesExpand = "author" | "categories"
// Direct + nested relations (depth 2)export type CommentsExpand = "article" | "article.author" | "article.categories" | "author"An XxxExpand type is only generated when the collection has at least one
relation field.
Relations map
Section titled “Relations map”Alongside XxxExpand, pbkit emits an XxxRelations map describing each forward
relation’s target record type and cardinality. The SDK uses this (with a small
set of shared helper types — BuildExpand, Split) to compute the typed
.expand result from the requested expand string:
export type ArticlesRelations = { author: { rec: UsersRecord; coll: "users"; multi: false } categories: { rec: CategoriesRecord; coll: "categories"; multi: true }}multi: true (the relation’s maxSelect > 1) means the expanded value is an
array. You normally don’t reference these directly — they exist so
getArticle(id, { expand: "author" }).expand?.author is typed as UsersRecord.
See Generated SDK → Typed expand.
The maximum path depth is controlled by types.expandDepth (default: 2):
export default { input: "https://my-pb.example.com", output: "./src/generated", types: { expandDepth: 1, // only direct relations, no nested paths },}With expandDepth: 1, CommentsExpand would be only "article" | "author".
Pass the native PocketBase comma-separated expand string to any read function.
The result is typed from that literal, so .expand is populated accordingly:
import { getArticle } from "./generated/sdk.gen"
const article = await getArticle("RECORD_ID", { expand: "author" })article.expand?.author // UsersRecordThe expand input itself is a plain string (no autocomplete) — typing the
result is the tradeoff. The XxxExpand union remains available if you want to
constrain or document valid paths yourself.
See Generated SDK → Typed expand for the full signatures.