Skip to content

Commit

Permalink
fix: flatten union in isCompatibleType
Browse files Browse the repository at this point in the history
  • Loading branch information
lawvs committed Mar 10, 2024
1 parent f19f193 commit cd00e6b
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/six-houses-exist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"zod-compare": patch
---

fix: flatten union in isCompatibleType
7 changes: 7 additions & 0 deletions src/__tests__/is-compatible-type.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,5 +132,12 @@ describe("isCompatibleType", () => {
z.number().or(z.string()).or(z.boolean()),
),
).toBe(true);

expect(isCompatibleType(z.string().or(z.boolean()), z.string())).toBe(
false,
);
expect(
isCompatibleType(z.string().or(z.boolean()), z.string().or(z.number())),
).toBe(false);
});
});
15 changes: 10 additions & 5 deletions src/is-compatible-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { z, type ZodType } from "zod";
import { isSameType } from "./is-same-type.ts";
import {
DEFAULT_COMPARE_TYPE_OPTIONS,
flatUnwrapUnion,
type IsCompatibleTypeOptions,
} from "./utils.ts";

Expand Down Expand Up @@ -56,21 +57,25 @@ export const isCompatibleType = (

// ZodUnion aka or
if (higherType instanceof z.ZodUnion && lowerType instanceof z.ZodUnion) {
for (let i = 0; i < higherType.options.length; i++) {
const match = lowerType.options.some((option: ZodType) =>
isCompatibleType(higherType.options[i], option, opts),
const higherOptions = flatUnwrapUnion(higherType);
const lowerOptions = flatUnwrapUnion(lowerType);
for (let i = 0; i < higherOptions.length; i++) {
const match = lowerOptions.some((option: ZodType) =>
isCompatibleType(higherOptions[i], option, opts),
);
if (!match) return false;
}
return true;
}
if (higherType instanceof z.ZodUnion) {
return higherType.options.every((option: ZodType) =>
const higherOptions = flatUnwrapUnion(higherType);
return higherOptions.every((option: ZodType) =>
isCompatibleType(option, lowerType, opts),
);
}
if (lowerType instanceof z.ZodUnion) {
return lowerType.options.some((option: ZodType) =>
const lowerOptions = flatUnwrapUnion(lowerType);
return lowerOptions.some((option: ZodType) =>
isCompatibleType(higherType, option, opts),
);
}
Expand Down

0 comments on commit cd00e6b

Please sign in to comment.