Skip to main content

parse vs typed

parse and typed solve different runtime tasks.

parse(unknown) for external-input validation

Use parse when data comes from outside your code and is not trusted.

import {number, object, string} from '@livon/schema';

const User = object({
name: 'User',
shape: {
id: string(),
age: number().int().min(18),
},
});

const unknownInput: unknown = JSON.parse(raw);
const user = User.parse(unknownInput);

Parameters in this example

User.parse(value):

  • value (unknown): untrusted incoming data.

typed(validInput) for invariant entrypoints

Use typed when data is already local and should be structurally aligned at compile time before entering runtime flow. typed is also useful for editor autocomplete, because the schema-derived type guides field suggestions while building payloads.

import {type Infer} from '@livon/schema';

type UserType = Infer<typeof User>;

const invalid: UserType = {id: 'u-1', age: '21'};
// TypeScript error: age must be number

const valid = User.typed({id: 'u-1', age: 21});

Autocomplete example:

const draft = User.typed({
id: 'u-1',
// IDE suggests: age
age: 21,
});

Parameters in this example

User.typed(value):

  • value (Infer<typeof User>): compile-time aligned value that is still checked against runtime constraints.

Compile-time alignment plus runtime constraints

typed shifts structural mismatches (field type/shape) to compile time, but constraint checks still run at runtime.

const maybeAdult = User.typed({id: 'u-1', age: 16});
// Compiles structurally (number), but runtime validation fails on min(18)

Practical rule

  • Use parse for external input.
  • Use typed for internal invariants before emitting or executing.
  • Both reinforce deterministic runtime checks.