Fully typed value objects for TypeScript build on top of zod
This library provides a small utility class that guarantees three things:
- ValueObjects are immutable
- ValueObjects are typesafe
- ValueObjects are value-equal (equal if their values are equal)
npm install zod-value-object # npm
yarn add zod-value-object # yarn
pnpm add zod-value-object # pnpm
import { ValueObject } from 'zod-value-object';
/* Primitives */
const schema = z.string().email();
class Email extends ValueObject('Email', schema) {}
const email = new Email('some@email.com');
console.log(email.value); // => "some@email.com"
/* Other Types */
const schema = z.object({ email: z.string() });
const schema = z.object({ email: Email }); // => Can use ValueObjects as schema
class Obj extends ValueObject('Obj', schema) {}
const obj = new Obj({ email: 'some@email.com' });
const obj = new Obj({ email: email }); // => Can use ValueObjects as input
const schema = z.string().email();
class Email extends ValueObject('Email', schema) {}
const email = new Email('some@email.com');
email.value = 'other@email.com'; // => throws Error, same on nested properties
const schema = z.string().email();
class Email extends ValueObject('Email', schema) {}
const email = new Email('some@email.com');
/* Wrong input */
const email = new Email(22); // => throws InvalidInputError
/* Use as parameter type */
const useEmail = (email: Email) => {
//
};
useEmail(email); // => works
useEmail('someEmail'); // => throws TypeScript error
class OtherString extends ValueObject('OtherString', schema) {}
const otherString = new OtherString('some@email.com');
useEmail(otherString); // => also throws TypeScript error
const schema = z.string().email();
class Email extends ValueObject('Email', schema) {}
const email = new Email('some@email.com');
const sameEmail = new Email('some@email.com');
const otherEmail = new Email('other@email.com');
console.log(email === sameEmail); // => true
console.log(email.equals(sameEmail)); // => true
console.log(email === otherEmail); // => false
console.log(email.equals(otherEmail)); // => false