Skip to content

Commit e6540a5

Browse files
committed
feat: add isZodTypeLike
1 parent 37ab082 commit e6540a5

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

src/__tests__/zod4.test.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
import { expectTypeOf, test } from 'vitest';
2-
import type { z as z3 } from 'zod/v3';
3-
import type { z as z4 } from 'zod/v4';
1+
import { describe, expect, expectTypeOf, it, test } from 'vitest';
2+
import { z as z3 } from 'zod/v3';
3+
import { z as z4 } from 'zod/v4';
4+
5+
import { isZodTypeLike } from '../zod4.js';
46

57
import type {
68
ZodErrorLike,
@@ -48,3 +50,22 @@ test('ZodTypeLike', () => {
4850
expectTypeOf<z4.ZodNumber>().toMatchTypeOf<ZodTypeLike<number>>();
4951
expectTypeOf<z4.ZodNumber>().not.toMatchTypeOf<ZodTypeLike<string>>();
5052
});
53+
54+
describe('isZodTypeLike', () => {
55+
it('should return true for Zod v3 types', () => {
56+
expect(isZodTypeLike(z3.object({}))).toBe(true);
57+
expect(isZodTypeLike(z3.number())).toBe(true);
58+
expect(isZodTypeLike(z3.any())).toBe(true);
59+
});
60+
it('should return true for Zod v4 types', () => {
61+
expect(isZodTypeLike(z4.object({}))).toBe(true);
62+
expect(isZodTypeLike(z4.number())).toBe(true);
63+
expect(isZodTypeLike(z4.any())).toBe(true);
64+
});
65+
it('should return false for an object without a standard schema', () => {
66+
expect(isZodTypeLike({})).toBe(false);
67+
});
68+
it('should return false for an object with a standard schema, but the incorrect vendor name', () => {
69+
expect(isZodTypeLike({ '~standard': { vendor: 'DNP' } })).toBe(false);
70+
});
71+
});

src/zod4.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { isObjectLike, isPlainObject } from './object.js';
2+
13
export type ZodIssueLike = {
24
[key: string]: any;
35
readonly code: string;
@@ -29,4 +31,16 @@ export type ZodTypeLike<TOutput, TInput = unknown> = {
2931
readonly _input: TInput;
3032
readonly _output: TOutput;
3133
safeParseAsync: (data: unknown) => Promise<ZodSafeParseResultLike<TOutput>>;
34+
'~standard': {
35+
[key: string]: any;
36+
vendor: string;
37+
};
3238
};
39+
40+
export function isZodTypeLike(arg: unknown): arg is ZodTypeLike<unknown> {
41+
if (!isObjectLike(arg)) {
42+
return false;
43+
}
44+
const standardSchema: unknown = Reflect.get(arg, '~standard');
45+
return isPlainObject(standardSchema) && standardSchema.vendor === 'zod';
46+
}

0 commit comments

Comments
 (0)