Documentation
TypeScript runtime validation with literals
Runtime schemas that look like TypeScript and compose like JavaScript. A schema is either a leaf such as string, or a plain object whose values are schemas.
npm i litetype
import { string, number, type Infer, parse } from 'litetype'
const User = {
name: string.min(1),
age: number.min(0),
'email?': string.email(),
}
type User = Infer<typeof User>
const user = parse(User, input)
Choose a validation verb
| Job | Use |
|---|---|
| Return data or throw | parse(schema, input) |
| Return a result union | safeParse(schema, input) |
| Narrow an unknown value | check(schema, input) |
| Predicate for a hot loop | compile(schema) |
Schemas compile automatically on first use. Call compile only when a hot loop should avoid the cache lookup.
Optional key ≠ undefined value
import { string } from 'litetype'
const A = { 'bio?': string } // bio may be omitted
const B = { bio: string.undefinable() } // bio is required, value may be undefined
The trailing ? mirrors a TypeScript optional property. It belongs to the key. Nullability belongs to the value.
Choose what happens to extra keys
All three validate name. They differ only in what happens to properties the schema does not declare.
import { parse, strict, string, strip } from 'litetype'
const User = { name: string }
const input = { name: 'Ada', role: 'admin' }
parse(User, input)
// → input itself: { name: 'Ada', role: 'admin' }
parse(strip(User), input)
// → a new object: { name: 'Ada' }
parse(strict(User), input)
// → throws because role is not declared
Normalize form values before validation
HTML forms return strings. Convert those raw values first, then validate the converted value.
import { coerce, parse, preprocess, string } from 'litetype'
// Treat an empty text field as "not provided"
const OptionalBio = preprocess(
value => value === '' ? undefined : value,
string.undefinable(),
)
parse(OptionalBio, '') // → undefined
parse(OptionalBio, 'Hello') // → 'Hello'
// Number inputs also arrive as strings
parse(coerce.number(), '42') // → 42 (a number)