Compare two Zod schemas recursively.
zod-compare
provides functions to compare Zod schemas, allowing you to determine whether two schemas are the same or compatible.
# npm
npm install zod zod-compare
# yarn
yarn add zod zod-compare
# pnpm
pnpm add zod zod-compare
import { z } from "zod";
import { isSameType, isCompatibleType } from "zod-compare";
isSameType(z.string(), z.string()); // true
isSameType(z.string(), z.number()); // false
isSameType(
z.object({ name: z.string(), other: z.number() }),
z.object({ name: z.string() }),
);
// false
isCompatibleType(
z.object({ name: z.string(), other: z.number() }),
z.object({ name: z.string() }),
);
// true
You can use createCompareFn
to create a custom comparison function.
import {
createCompareFn,
isSameTypePresetRules,
defineCompareRule,
} from "zod-compare";
const customRule = defineCompareRule(
"compare description",
(a, b, next, recheck, context) => {
// If the schemas are not having the same description, return false
if (a.description !== b.description) {
return false;
}
return next();
},
);
const strictIsSameType = createCompareFn([
customRule,
...isSameTypePresetRules,
]);
You can pass a context
object to the comparison functions to get more information about the comparison process.
const context = {
stacks: [],
};
isSameType(
z.object({ name: z.string(), other: z.number() }),
z.object({ name: z.string(), other: z.string() }),
context,
);
// type stacks = { name: string; target: [a: ZodType, b: ZodType]; result: boolean; }[]
console.log(context.stacks);
The default rules isSameTypePresetRules
will disregard any custom validations like min
, max
, length
, among others. Additionally, these default rules cannot be utilized for comparing ZodLazy
, ZodEffects
, ZodDefault
, ZodCatch
, ZodPipeline
, ZodTransformer
, ZodError
types.
If there is a necessity to compare these types, custom rules can be established using defineCompareRule
.
Compares two Zod schemas and returns true
if they are the same.
import { isSameType } from "zod-compare";
type isSameType: (a: ZodType, b: ZodType, context?: CompareContext) => boolean;
Creates a custom comparison function.
import { createCompareFn, defineCompareRule } from "zod-compare";
type defineCompareRule = (
name: string,
rule: CompareFn,
) => {
name: string;
rule: CompareFn;
};
type createCompareFn = (rules: CompareRule[]) => typeof isSameType;
// Example
const isSameType = createCompareFn(isSameTypePresetRules);
const isCompatibleType = createCompareFn(isCompatibleTypePresetRules);
Compares two Zod schemas and returns true
if they are compatible.
import { isCompatibleType } from "zod-compare";
// The `higherType` should be a looser type
// The `lowerType` should be a stricter type
type isCompatibleType: (higherType: ZodType, lowerType: ZodType) => boolean;
You can use the preset rules isSameTypePresetRules
and isCompatibleTypePresetRules
to create custom comparison functions.
import { isSameTypePresetRules, isCompatibleTypePresetRules } from "zod-compare";
type isSameTypePresetRules: CompareRule[];
type isCompatibleTypePresetRules: CompareRule[];
// Example
const yourIsSameType = createCompareFn([customRule, ...isSameTypePresetRules]);
type CompareContext = {
stacks?: {
name: string;
target: [a: ZodType, b: ZodType];
}[];
} & Record<string, unknown>;
type CompareFn = (
a: ZodType,
b: ZodType,
next: () => boolean,
recheck: (a: ZodType, b: ZodType) => boolean,
context: CompareContext,
) => boolean;
type CompareRule = {
name: string;
compare: CompareFn;
};
MIT