simple-runtypes
simple-runtypes copied to clipboard
Add lazy or some way to create recursive types
zod etc have a lazy
combinator that allows creating recursive validators.
For example, given this TS type:
type Node = {
label: string;
children: Node[];
};
There is no way to define this with simple-runtypes
You're right, this is missing. Wasn't a priority for me as I've never encountered a recursive type in any API that I needed to validate.
Do you happen to have any real world examples (just curious)?
I realized that I can do this with runtype
but maybe there is room for simplifacation?
import * as t from 'simple-runtypes';
type Node = {
children: Node[];
label: string;
};
const node: t.Runtype<Node> = t.record({
children: t.array(
t.runtype((c) => {
const r = t.use(node, c);
if (!r.ok) {
return r.error;
}
return r.result;
}),
),
label: t.string(),
});
Maybe lazy can be defined as:
import * as t from 'simple-runtypes';
function lazy<T>(fn: () => t.Runtype<T>): t.Runtype<T> {
return t.runtype(v => {
const r = t.use(fn(), v);
return r.ok ? r.result : r.error;
});
}
then the Node example becomes:
import * as t from 'simple-runtypes';
type Node = {
children: Node[];
label: string;
};
const node: t.Runtype<Node> = t.record({
children: t.array(
lazy(() => node),
),
label: t.string(),
});
The real world scenarios include tree like data structures... Filesystems, btrees etc.
Thx, that looks good. Is it just something that is missing in theory or do you have a case at hand where you need this feature?
I know that filesystems are in theory a tree, but the APIs I've been using in the past will just return a flat list of files/dirs for single directories, never full fledged trees.
If you like you can submit a PR but I will also add it by myself when I have some time.
And thanks for the suggestion!
We currently use zod (and superstruct) and have a JSON type that is recursive.