API 全表
litetype 的全部公共 API,逐个列出。叙事导览看 首页;这里是查字典用的平表。
npm i litetype两个入口:
import { /* 下面全部核心 */ } from 'litetype'
import { fromJsonSchema, toJsonSchema } from 'litetype/jsonschema'import 'litetype' 零运行时依赖、不拉 jsonschema;后者按需走子路径。
动词(外置,吃 schema + data)
函数 | 签名 | 行为 |
|---|---|---|
|
| 通过返回 typed data,失败 |
|
| 不抛,返回判别结果 |
|
| 类型守卫,收窄 |
import { string, number, parse, safeParse, check } from 'litetype'
const User = { name: string.min(1), age: number.min(0) }
parse(User, input) // typed data | throw
const r = safeParse(User, input) // r.success ? r.data : r.error
if (check(User, input)) input.name // input 收窄为 { name; age }失败收集整棵树所有错误(不在首错中断),每条 Issue 带 path + message + code。
类型
import { type Infer, type InferInput, type Schema, type Shape } from 'litetype'
const User = { name: string, "email?": string.email() }
type User = Infer<typeof User> // { name: string; email?: string } ← Output
type UserIn = InferInput<typeof User> // transform/default 的 Input 侧Infer<S>— 取 Output(校验后的值类型)。InferInput<S>— 取 Input(transform入参、default/optional字段 Input 侧可选)。Schema<T>/Shape— 叶/复合节点与裸 shape 的类型。
基础类型(leaf)
import { string, number, boolean, date, unknown } from 'litetype'导出 | Infer | 备注 |
|---|---|---|
|
| |
|
| 接受 |
|
| |
|
|
|
|
| 接受一切,类型保持 unknown |
string 的方法
每个都接可选 message 末参,给了覆盖默认错信息。
string.min(n, msg?) // 长度 >= n
string.max(n, msg?) // 长度 <= n
string.length(n, msg?) // 长度 === n
string.email(msg?) // 词法判定(禁正则)
string.url(msg?) // new URL() 可解析
string.uuid(msg?) // 8-4-4-4-12 词法判定
string.datetime(msg?) // ISO datetime 词法判定
string.ip(msg?) // IPv4 + IPv6 词法判定
string.startsWith(s, msg?)
string.endsWith(s, msg?)
string.includes(s, msg?)
string.regex(re, msg?) // 唯一允许的正则:校验用户 data,非解析结构化文本number 的方法
number.min(n, msg?) // >= n
number.max(n, msg?) // <= n
number.gt(n, msg?) // > n
number.lt(n, msg?) // < n
number.int(msg?) // 整数
number.finite(msg?) // 排除 Infinity / -Infinity
number.positive(msg?) // > 0
number.nonnegative(msg?) // >= 0
number.multipleOf(n, msg?) // 整除 n(整数缩放,不吃浮点误差)date 的方法
date.min(d, msg?) // >= d(Date)
date.max(d, msg?) // <= d组合子(所有 schema 都有的方法)
string/number 等 leaf 与 array/union/record 等复合节点同构持有这 6 个方法,可任意链式。
import { string, number } from 'litetype'
string.transform(s => s.length) // 校验后变换值,Output 可异于 Input
number.refine(n => n % 2 === 0, '必须是偶数') // 加谓词,不改类型
string.default('user') // 缺值(undefined)时填默认,Input 侧可省
string.optional() // 放行 undefined(值层,与 key 的 "?" 正交)
string.nullable() // 放行 null
number.nullish() // 放行 undefined + null裸 shape({name: string})无方法,对它整体变换用自由函数 transform(shape, fn)。
自由函数版(裸 shape 用)
import { transform, fallback } from 'litetype'
transform({ a: string }, obj => obj.a) // 对裸 shape 做 transform
fallback(number, 0) // 校验失败吞 issue 返回兜底值(zod 的 .catch())fallback 是自由函数不是方法(catch 是保留字,且给 Schema 接口加 this-返回方法会撑爆类型机)。
default 兜「缺」、fallback 兜「坏」。
复合类型
import { array, union, tuple, record, enum_, literal, lazy } from 'litetype'
array(string.min(1)) // T[]
union(literal('a'), literal('b')) // 变长参数,全败 collect-all 报每支原因
tuple(string, number) // [string, number],变长参数
record(number) // { [k: string]: number }
record(enum_(['a', 'b']), number) // 两参:key 也校验,key 类型收窄
enum_(['admin', 'user']) // 数组参数
literal('user') // 字面量
lazy(() => Tree) // 递归唯一逃逸舱(JS 字面量无法自引用)
const Tree = { value: string, "children?": array(lazy(() => Tree)) }discriminatedUnion — 判别联合
import { discriminatedUnion, literal, number } from 'litetype'
const Shape = discriminatedUnion('type',
{ type: literal('circle'), radius: number },
{ type: literal('square'), side: number },
)
// 按判别 key O(1) 选支,只校验那支,错误精准落在那支每支是裸 shape,判别 key 必须是 literal(...)。
对象操作(schema 即数据,原生 JS 全可用)
schema 是裸值,所以不需要 .extend()/.pick()/.omit() —— spread 是 extend,挑字段是 pick,解构 rest 是 omit。可选键("key?")全程保留。
const Post = { title: string, ...Timestamps } // extend / merge(spread)
const Admin = { ...User, role: literal('admin') } // 覆写(后者赢)
const Pub = { name: User.name, "email?": User["email?"] } // pick(手挑)
const { age: _, ...NoAge } = User // omit(解构 rest)partial / required — 批量改 key 可选性
import { partial, required } from 'litetype'
partial(User) // 每个 key 加 "?" → Infer = Partial<User>
required(User) // 每个 key 去 "?" → Infer = Required<User>纯 shape 字符串变换,零节点,只作用裸 shape。
strict — 闭集(拒多余 key)
import { strict } from 'litetype'
const Exact = strict({ name: string, "age?": number })
parse(Exact, { name: 'Ann', role: 'x' }) // FAIL: role unexpected key默认忽略多余 key;strict 只作用本层,类型透明(Infer<strict(S)> === Infer<S>)。
coerce — 掰输入类型再校验
import { coerce, number } from 'litetype'
coerce.number() // '42' / 42 → 42(Infer=number, InferInput=unknown)
coerce.boolean() // 'true' / 'false' → 布尔(严格白名单)
coerce.date() // '2020-01-01' → Date 实例
coerce.string() // → string
coerce.number(number.min(0)) // 细化约束写进 inner表单 / query string / env var 这类「输入永远是字符串」的边界用它。
describe — 挂人读描述
import { describe, descriptionOf, string } from 'litetype'
const Q = describe(string, '搜索关键词') // 给 schema 挂描述(toJsonSchema / 模型工具用)
descriptionOf(Q) // '搜索关键词'describe 是自由函数 + 冻结透传节点,零行为变化。
错误投影(flatten / treeify / prettify)
error.issues 是扁平 { path, message, code }[]。三个自由函数重整成消费场景形状,吃 SchemaError 或裸 issues[] 都行。
import { flatten, treeify, prettify, safeParse, array, string } from 'litetype'
const r = safeParse({ name: string.min(2), tags: array(string.min(1)) }, { name: 'x', tags: ['ok', ''] })
if (!r.success) {
flatten(r.error)
// { formErrors: [], fieldErrors: { name: ['length must be >= 2'], tags: ['length must be >= 1'] } }
// 单层投影(zod v3 .flatten() 同形)。表单 / API 400 体最常用。
treeify(r.error)
// { errors: [], properties: { name: {errors:[...]}, tags: { errors:[], items: [null, {errors:[...]}] } } }
// 沿 path 下钻的镜像树(zod v4 treeifyError 同形)。深层嵌套精确定位。
prettify(r.error) // 也可 prettify(r.error.issues)
// ✖ length must be >= 2\n → at name\n✖ length must be >= 1\n → at tags.1
// 人读多行串,日志 / CLI。
}Issue 的形状
import { type Issue, type IssueCode, SchemaError } from 'litetype'
interface Issue {
path: ReadonlyArray<PropertyKey> // 错误位置
message: string // dev-facing 英文默认(可逐 check 覆盖)
code: IssueCode // 机读码,消费侧按 code 分支不靠匹配 message
params?: Record<string, unknown> // 结构化约束参数(i18n / 反读用)
}IssueCode 取值:invalid_type invalid_value too_small too_big not_multiple_of invalid_string unrecognized_key invalid_union custom。
Standard Schema 生态
实现 Standard Schema ~standard 接口,接入 tRPC / react-hook-form / TanStack。叶子天然兼容;裸 shape 在生态边界包一次 standard()。
import { standard } from 'litetype'
t.procedure.input(standard(User))
useForm({ resolver: standardSchemaResolver(standard(User)) })JSON Schema 互转(litetype/jsonschema)
走子路径,import 'litetype' 零增重。接 ajv 用户群 / 出 OpenAPI / 前端表单。
import { fromJsonSchema, toJsonSchema } from 'litetype/jsonschema'
import { string, number, parse } from 'litetype'
// JSON Schema → schema → 校验真数据
const sch = fromJsonSchema({
type: 'object',
properties: { name: { type: 'string', minLength: 1 }, age: { type: 'integer', minimum: 0 } },
required: ['name', 'age'],
})
parse(sch, { name: 'al', age: 3 })
// schema → JSON Schema(约束随关键字一起反读出来)
toJsonSchema({ id: string.uuid(), age: number.int().min(0) })
// { type:'object', properties:{ id:{type:'string',format:'uuid'}, age:{type:'integer',minimum:0} }, required:[...] }约束往返:string.min(1)/email/uuid/number.int().min(0)/multipleOf 等 JSON-Schema-可表达约束经 toJsonSchema → fromJsonSchema 重建后仍 enforce(不只保 type)。
支持映射:string + minLength/maxLength/format(email|uri|uuid|date-time)/pattern、number/integer + minimum/maximum/exclusiveMinimum/exclusiveMaximum/multipleOf、array/object/enum/const/oneOf|anyOf/$ref(→lazy)/additionalProperties:false(→strict)。
边界(文档化,非 bug):
无标准关键字的约束(
startsWith/endsWith/includes/ip)不反读 —— 仍只产type,不谎报。transform/refine/coerce是运行时变换/谓词,无 JSON Schema 对应 ——toJsonSchema命中即抛cannot serialize。fromJsonSchema碰allOf/if-then/patternProperties抛unsupported,不静默吞。