Using the Zod validation library with TypeScript has been a great experience for me so far.
I am currently exploring the best pattern to extend Zod Schema with class-like functionality, starting with a Vector3 schema like this:
const Vector3Schema = z.object({
x: z.number(),
y: z.number(),
z: z.number(),
})
type Vector3 = z.infer<typeof Vector3Schema>;
Having the type associated with Zod validation is neat and clean, but now I'm thinking about adding some class-like features to the Vector3 type.
My OOP background makes me lean towards adding basic functionalities to the type in a class-like manner, such as:
let vec1 = Vector3Schema.parse({x: 1, y: 2, z: 3});
let vec2 = Vector3Schema.parse({x: 4, y: 5, z: 6});
let distance = vec1.distance(vec2);
vec1.normalize();
The challenge is how to achieve this without duplicating class definitions and validation logic. Is there a way to parse a Zod schema into a class instance or extend the parsed type with additional functionalities?
Or perhaps it's time to embrace a more functional approach:
function normalize(v: Vector3) {...}
function distance(v1: Vector3, v2: Vector3) {...}
let vec1 = Vector3Schema.parse({x: 1, y: 2, z: 3});
let vec2 = Vector3Schema.parse({x: 4, y: 5, z: 6});
let calculatedDistance = distance(vec1, vec2);
vec1 = normalize(vec1);
I'm open to hearing your thoughts and ideas on this topic.