Validating data with a schema
One schema defines runtime validation and the TypeScript type.
SchemaDecoder validates input and returns data with the expected structure.
In schemas.ts, board width and height are validated as positive integers. Extract that check into BoardSchema for this example:
import { SchemaDecoder } from '@gamedevland/engine/validation';
import type { InferDecoded } from '@gamedevland/engine/validation';
export class BoardSchema {
static readonly decoder = SchemaDecoder.object({
width: SchemaDecoder.number({ integer: true, min: 1 }),
height: SchemaDecoder.number({ integer: true, min: 1 }),
});
}
export type BoardConfig = InferDecoded<typeof BoardSchema.decoder>;
InferDecoded derives the type from the schema: a separate interface with the same fields is not needed.
Now validate the JSON data:
const board = SchemaDecoder.decode(raw, BoardSchema.decoder, 'board.json');
Here, raw is input of type unknown. The board.json label helps locate the source of an error.
The object, readonlyArray, string, number, boolean, record, optional and enumOf combinators describe nested structures. Constraints express valid values: for example, a slot number is an integer from 0 to 2. The domain model checks whether a piece fits into free cells, since that depends on the current board.