Skip to content

Commit 1d5808a

Browse files
committed
Fixed type inference with Infer for Zod 4
1 parent 24cc32a commit 1d5808a

File tree

2 files changed

+29
-17
lines changed

2 files changed

+29
-17
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1616
- Possibly fixed the SuperDebug broken import on Svelte 5 in enforced runes mode [#599](https://github.com/ciscoheat/sveltekit-superforms/issues/599)
1717
- Zod 4 error messages should now take the current locale into account as default. [#618](https://github.com/ciscoheat/sveltekit-superforms/issues/618), [#639](https://github.com/ciscoheat/sveltekit-superforms/issues/639)
1818
- Zod 3 fix for URL parsing - A default boolean value of `true` returned `false` when parsing a URL with `superValidate`. [#633](https://github.com/ciscoheat/sveltekit-superforms/issues/633)
19+
- Fixed type inference with `Infer` for Zod 4
1920

2021
## [2.27.4] - 2025-10-14
2122

src/lib/adapters/typeSchema.ts

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import type {
1515
} from 'valibot';
1616
import type { Schema as Schema$2, InferType } from 'yup';
1717
import type { ZodTypeAny, input, output } from 'zod/v3';
18-
import type { $ZodType, input as zod4Input, output as zod4Output } from 'zod/v4/core';
18+
import type { $ZodType as $Zod4Type, input as zod4Input, output as zod4Output } from 'zod/v4/core';
1919
import type { SchemaTypes, Infer as VineInfer } from '@vinejs/vine/types';
2020
import type { FromSchema, JSONSchema } from 'json-schema-to-ts';
2121
import type { Struct, Infer as Infer$2 } from 'superstruct';
@@ -93,14 +93,20 @@ type CustomSchema<T = any> = (data: unknown) => Promise<T> | T;
9393
interface CustomResolver extends Resolver {
9494
base: CustomSchema;
9595
input: this['schema'] extends CustomSchema
96-
? keyof this['schema'] extends never
97-
? Awaited<ReturnType<this['schema']>>
98-
: never
96+
? // Exclude schemas that are Zod types (they have _def property)
97+
this['schema'] extends { _def: unknown }
98+
? never
99+
: keyof this['schema'] extends never
100+
? Awaited<ReturnType<this['schema']>>
101+
: never
99102
: never;
100103
output: this['schema'] extends CustomSchema
101-
? keyof this['schema'] extends never
102-
? Awaited<ReturnType<this['schema']>>
103-
: never
104+
? // Exclude schemas that are Zod types (they have _def property)
105+
this['schema'] extends { _def: unknown }
106+
? never
107+
: keyof this['schema'] extends never
108+
? Awaited<ReturnType<this['schema']>>
109+
: never
104110
: never;
105111
}
106112

@@ -135,11 +141,10 @@ interface ZodResolver extends Resolver {
135141
}
136142

137143
interface Zod4Resolver extends Resolver {
138-
base: $ZodType;
139-
input: this['schema'] extends $ZodType ? zod4Input<this['schema']> : never;
140-
output: this['schema'] extends $ZodType ? zod4Output<this['schema']> : never;
144+
base: $Zod4Type;
145+
input: this['schema'] extends $Zod4Type ? zod4Input<this['schema']> : never;
146+
output: this['schema'] extends $Zod4Type ? zod4Output<this['schema']> : never;
141147
}
142-
143148
interface VineResolver extends Resolver {
144149
base: SchemaTypes;
145150
input: this['schema'] extends SchemaTypes
@@ -229,14 +234,20 @@ export type Registry = {
229234
};
230235

231236
type Infer<TSchema extends Schema, Keys extends keyof Registry = keyof Registry> = UnknownIfNever<
232-
{
233-
[K in Keys]: IfDefined<InferOutput<Registry[K], TSchema>>;
234-
}[Keys]
237+
// If schema has _zod property, it's Zod v4 - use only zod4 resolver
238+
TSchema extends { _zod: unknown }
239+
? IfDefined<InferOutput<Registry['zod4'], TSchema>>
240+
: {
241+
[K in Keys]: IfDefined<InferOutput<Registry[K], TSchema>>;
242+
}[Keys]
235243
>;
236244
type InferIn<TSchema extends Schema, Keys extends keyof Registry = keyof Registry> = UnknownIfNever<
237-
{
238-
[K in Keys]: IfDefined<InferInput<Registry[K], TSchema>>;
239-
}[Keys]
245+
// If schema has _zod property, it's Zod v4 - use only zod4 resolver
246+
TSchema extends { _zod: unknown }
247+
? IfDefined<InferInput<Registry['zod4'], TSchema>>
248+
: {
249+
[K in Keys]: IfDefined<InferInput<Registry[K], TSchema>>;
250+
}[Keys]
240251
>;
241252

242253
/*

0 commit comments

Comments
 (0)