export function minizod() {
type UnknownInput = unknown | undefined | null;
type ZType =
| ZAny
| ZUnknown
| ZPromise<ZType>
| ZFunction<ZTuple, ZType>
| ZString
| ZTuple<
[
ZType,
...ZType[],
] | []
>
| ZArray<ZType>
| ZObject<Record<string, ZType>>
| ZRecord<ZType>;
type Infer<T extends ZType> = T["type"] extends "unknown" ? unknown
: T["type"] extends "string" ? string
: T extends ZTuple ? InferTuple<T>
: T["type"] extends "object" ? InferObject<T>
: T extends ZRecord<ZType> ? InferRecord<T>
: T["type"] extends "array" ? InferArray<T>
: T["type"] extends "promise" ? InferPromise<T>
: T["type"] extends "any" ? any
: "invalid type";
type InferPromise<T> = T extends ZPromise<infer P extends ZType>
? Promise<Infer<P>>
: never;
type InferArray<T> = T extends ZArray<infer P extends ZType> ? Array<Infer<P>>
: never;
type InferRecord<T> = T extends ZRecord<infer V extends ZType>
? Record<string, Infer<V>>
: never;
type InferObject<T> = T extends
ZObject<infer Obj extends Record<string, ZType>> ? {
[k in keyof Obj]: Infer<Obj[k]>;
}
: never;
type InferFunction<T> = T extends ZFunction<
infer Args extends ZTuple<
[
ZType,
...ZType[],
] | []
>,
infer Ret extends ZType
> ? (...args: InferTuple<Args>) => Infer<Ret>
: never;
type InferForEach<T extends ZType[]> = T extends [] ? [] : T extends [
infer First extends ZType,
] ? [
Infer<First>,
]
: T extends [
infer First extends ZType,
...infer Rest extends ZType[],
] ? [
Infer<First>,
...InferForEach<Rest>,
]
: [];
type InferTuple<
T extends ZTuple<
[] | [
ZType,
...ZType[],
]
>,
> = T extends ZTuple<[]> ? [] : T extends ZTuple<[
infer First extends ZType,
...infer Rest extends ZType[],
]> ? [
Infer<First>,
...InferForEach<Rest>,
]
: [];
class ZRecord<V extends ZType> {
type: "record" = "record";
__vals: V;
constructor(__vals: V) {
this.__vals = __vals;
}
async parse(val: UnknownInput): Promise<Record<string, Infer<V>>> {
if (val === undefined || val === null)
throw new Error("undefined");
for (const key in val) {
if (typeof key !== "string")
throw new Error(`Key ${key} is not a string`);
await this.__vals.parse(val[key]);
}
return val as any;
}
parseSync(val: UnknownInput): Record<string, Infer<V>> {
if (val === undefined || val === null)
throw new Error("undefined");
for (const key in val) {
if (typeof key !== "string")
throw new Error(`Key ${key} is not a string`);