zod schema type mapper,its can create new schema base on existed zod schema with condition type tester.
export const dataSchema = z.object({
id: z.string(),
age: z.number(),
createdAt: z.date(),
arrayDate: z.date().array(),
arrayNumber: z.number().array(),
testUnion: z.number().or(z.date()),
});
export type Data = z.infer<typeof dataSchema>;
// type Data = {
// id: string;
// age: number;
// createdAt: Date;
// arrayDate: Date[];
// arrayNumber: number[];
// testUnion: number | Date;
// }
export const data: Data = {
age: 1,
id: "1",
createdAt: new Date("2024-12-31T10:51:52.587Z"),
arrayDate: [new Date("2024-12-31T10:51:52.587Z")],
arrayNumber: [1, 2, 3],
testUnion: 1,
};const jsonSchema = convertSchema(
dataSchema,
(schema) => schema instanceof z.ZodDate,
(schema) => schema.transform((value) => value.toISOString())
)
.convert(
(schema) => schema instanceof z.ZodNumber,
(schema) => schema.transform((value) => value.toString())
)
.schema();
type Json = z.infer<typeof jsonSchema>;
// type Json = {
// id: string;
// age: string;
// createdAt: string;
// arrayDate: string[];
// arrayNumber: string[];
// testUnion: string;
// }
console.log(jsonSchema.parse(data));
// {
// id: '1',
// age: '1',
// createdAt: '2024-12-31T10:51:52.587Z',
// arrayDate: [ '2024-12-31T10:51:52.587Z' ],
// arrayNumber: [ '1', '2', '3' ],
// testUnion: '1'
// }const jsonMapper = createMapper(
dataSchema,
(schema) => schema instanceof z.ZodDate,
(schema) => schema.transform((value) => value.toISOString()),
(schema) =>
z
.string()
.datetime()
.transform((value) => new Date(value))
.pipe(schema)
)
.create(
(schema) => schema instanceof z.ZodNumber,
(schema) => schema.transform((value) => value.toString()),
(schema) =>
z
.string()
.transform((value) => Number(value))
.pipe(schema)
)
.mapper();
type Json = z.infer<typeof jsonMapper.encoderSchema>;
// type Json = {
// id: string;
// age: string;
// createdAt: string;
// arrayDate: string[];
// arrayNumber: string[];
// testUnion: string;
// }
const jsonData: Json = {
age: "1",
id: "1",
createdAt: "2024-12-31T10:51:52.587Z",
arrayDate: ["2024-12-31T10:51:52.587Z"],
arrayNumber: ["1", "2", "3"],
testUnion: "1",
};
console.log(jsonMapper.encode(data));
// {
// id: '1',
// age: '1',
// createdAt: '2024-12-31T10:51:52.587Z',
// arrayDate: [ '2024-12-31T10:51:52.587Z' ],
// arrayNumber: [ '1', '2', '3' ],
// testUnion: '1'
// }
console.log(jsonMapper.decode(jsonData));
// {
// id: '1',
// age: 1,
// createdAt: 2024-12-31T10:51:52.587Z,
// arrayDate: [ 2024-12-31T10:51:52.587Z ],
// arrayNumber: [ 1, 2, 3 ],
// testUnion: 1
// }- z.custom
- z.instanceof
Since z.custom & z.instanceOf just combined ZodAny with superRefine,doesnt have existed ZodType class.
I have no way to indetify their schema in runtime.:(
ok,appearent there is workaround. But can only indetify schema base on instance instead of runtime class type or more general way. check example
z.instanceof can replaced with instanceOfClass(ZodInstaceOfClass) class come with package provide some helper functions.
instanceOfClass support private constructor.
export class Test {
name: string | undefined;
constructor(name: string) {
this.name = name;
}
}
export const dataSchema = z.object({
// value: z.instanceof(Test),
value: instanceOfClass(Test),
});
export type Data = z.infer<typeof dataSchema>;
// type Data = {
// value: Test;
// }
export const data: Data = {
value: new Test("hello world"),
};
const jsonMapper = createMapper(
dataSchema,
(schema) => ZodInstaceOfClass.isSchema(Test, schema),
(schema) => schema.transform((value) => value.name),
(schema) =>
z
.string()
.transform((value) => new Test(value))
.pipe(schema)
).mapper();
type Json = z.infer<typeof jsonMapper.encoderSchema>;
// type Json = {
// value: string | undefined;
// }
const jsonData: Json = {
value: "hello world",
};
console.log(jsonMapper.encode(data));
// { value: 'hello world' }
console.log(jsonMapper.decode(jsonData));
// { value: Test { name: 'hello world' } }const testSchema = z.instanceof(Test);
export const dataSchema = z.object({
// value: z.instanceof(Test),
value: testSchema,
});
export type Data = z.infer<typeof dataSchema>;
// type Data = {
// value: Test;
// }
export const data: Data = {
value: new Test("hello world"),
};
const jsonMapper = createMapper(
dataSchema,
(schema) => isSchema(testSchema, schema), // type prediction helper method come with package
(schema) => schema.transform((value) => value.name),
(schema) =>
z
.string()
.transform((value) => new Test(value))
.pipe(schema)
).mapper();-
ZodString
-
ZodNumber
-
ZodNaN
-
ZodBigInt
-
ZodBoolean
-
ZodDate
-
ZodLiteral
-
ZodNull
-
ZodEnum
-
ZodNativeEnum
-
ZodUndefined
-
ZodVoid
-
ZodObject
-
ZodArray
-
ZodUnion
-
ZodNullable
-
ZodOptional
- ZodLazy
- ZodPromise
- ZodFunction
- ZodMap
- ZodSet
- ZodRecord
-
ZodNever - ZodTuple