zod
Version:
Typescript-first schema declaration and validation library with static type inference
87 lines (77 loc) • 2.64 kB
text/typescript
import * as z from './base';
import { ZodUndefined } from './undefined';
import { ZodNull } from './null';
import { ZodUnion } from './union';
import { ZodIntersection } from './intersection';
export interface ZodObjectDef<T extends z.ZodRawShape = z.ZodRawShape>
extends z.ZodTypeDef {
t: z.ZodTypes.object;
shape: T; //{ [k in keyof T]: T[k]['_def'] };
}
type OptionalKeys<T extends z.ZodRawShape> = {
[k in keyof T]: undefined extends T[k]['_type'] ? k : never;
}[keyof T];
type RequiredKeys<T extends z.ZodRawShape> = Exclude<keyof T, OptionalKeys<T>>;
type ObjectType<T extends z.ZodRawShape> = {
[k in OptionalKeys<T>]?: T[k]['_type'];
} &
{ [k in RequiredKeys<T>]: T[k]['_type'] };
// type adsf = OptionalKeys<{name:ZodString}>;
// type asdfqwe = {name:ZodString}['name']['_type']
// type lkjljk = (undefined) extends (string) ? true : false
export class ZodObject<T extends z.ZodRawShape> extends z.ZodType<
ObjectType<T>, // { [k in keyof T]: T[k]['_type'] },
ZodObjectDef<T>
> {
toJSON = () => ({
t: this._def.t,
shape: Object.assign(
{},
Object.keys(this._def.shape).map(k => ({
[k]: this._def.shape[k].toJSON(),
}))
),
});
merge = <U extends ZodObject<any>>(other: U): ZodObject<T & U> => {
const currShape = this._def.shape;
const mergeShape = other._def.shape;
const currKeys = Object.keys(currShape);
const mergeKeys = Object.keys(mergeShape);
const sharedKeys = currKeys.filter(k => mergeKeys.indexOf(k) !== -1);
const sharedShape: any = {};
for (const k of sharedKeys) {
sharedShape[k] = ZodIntersection.create(currShape[k], mergeShape[k]);
}
const merged: ZodObject<T & U> = new ZodObject({
t: z.ZodTypes.object,
shape: {
...(this._def.shape as object),
...(other._def.shape as object),
...sharedShape,
},
}) as any;
return merged;
};
// merge = <U extends z.ZodRawShape>(
// other: ZodObject<U>
// ): ZodObject<MergeShapes<T, U>> => {
// const merged: ZodObject<MergeShapes<T, U>> = new ZodObject({
// t: z.ZodTypes.object,
// shape: {
// ...this._def.shape,
// ...other._def.shape,
// },
// }) as any;
// return merged;
// };
optional: () => ZodUnion<[this, ZodUndefined]> = () =>
ZodUnion.create([this, ZodUndefined.create()]);
nullable: () => ZodUnion<[this, ZodNull]> = () =>
ZodUnion.create([this, ZodNull.create()]);
static create = <T extends z.ZodRawShape>(shape: T): ZodObject<T> => {
return new ZodObject({
t: z.ZodTypes.object,
shape,
});
};
}