ZodZ
Zod2y ago
k9

k9 - Hello! I'm getting up to speed. The Comple...

Hello! I'm getting up to speed. The Complex Schema Validation section of zod-tutorial talks about how to preresent what would be a union type in a schema. That doesn't quite do what I'm looking for

I have defined types with a string template type e.g.

export type PlayerId = `p${string}`;
export type GameId = `g${string}`;
export type SpectatorId = `s${string}`;


which has been a useful way to ensure we don't send the wrong IDs throughout our ecosystem. Those IDs come through JSON schemas I would like to validate with Zod.

I can represent validations (there's already methods that ensure the strings are of their type, e.g.

export function isGameId(object: any): object is GameId {
  return object?.charAt?.(0) === 'g';
}


So, erm, so GameId is everywhere in the codebase, so I have to be careful about refactoring the API. But how can I define a type that a) only accepts a string and b) only if it matches type GameId and c) z.infer() can describe it as type
GameId
?
Solution
Should just be the following:
type GameId = `g${string}`;

const isGameId = (value: unknown): value is GameId => {
  return typeof value === "string" && value.startsWith("g");
};

const schema = z.string().refine(isGameId);
const result = schema.parse("g123");
//    ^? `g${string}`
Was this page helpful?