Skip to content

TypeScript ​

tinyval is written in TypeScript. The data type is inferred from the schema, so you don't need to declare an interface separately.

Infer — type from a schema ​

ts
import { object, string, number, optional, array, oneOf, type Infer } from 'tinyval';

const User = object({
  name: string(),
  age: optional(number()),
  role: oneOf(['admin', 'user']),
  tags: array(string()),
});

type User = Infer<typeof User>;
// {
//   name: string;
//   role: 'admin' | 'user';
//   tags: string[];
//   age?: number | undefined;
// }

Fields wrapped in optional without a default become optional (?). With transform the type is the result of the transformation.

Narrowing the result ​

validate returns a union: after checking valid, TypeScript knows whether data exists:

ts
const result = validate(User, input);

if (result.valid) {
  result.data.name; // string
} else {
  result.data;      // undefined
  result.errors;    // Record<string, string>
}

parse returns Infer<typeof User> directly.

Rule compatibility ​

A rule must match the schema type — the error is shown before you run the code:

ts
pipe(number(), minLength(2)); // error: minLength works with strings and arrays
pipe(string(), min(1));       // error: min works with numbers

Types in custom checks ​

The value type of check can be set explicitly:

ts
const even = check<number>((v) => v % 2 === 0, 'Must be even');

Exported types ​

TypeDescription
Schema<T>A schema that returns a value of type T
Infer<S>The data type of schema S
Result<T>The result of validate
IssueAn error: { code, message, path, params }
MessageA string or a function (params) => string
OptionsValidation options: { all?, abortEarly?, messages?, labels?, maxDepth? } — see validate
Action<T>A rule or transform for pipe
InfoThe second argument of check: { parent, root }

See also ​