Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit b588d2c

Browse filesBrowse files
committed
Improve z.function typing. Add .def
1 parent 7bd15ed commit b588d2c
Copy full SHA for b588d2c

File tree

Expand file treeCollapse file tree

4 files changed

+64
-47
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

4 files changed

+64
-47
lines changed
Open diff view settings
Collapse file

‎packages/zod/src/v4/classic/tests/function.test.ts‎

Copy file name to clipboardExpand all lines: packages/zod/src/v4/classic/tests/function.test.ts
+9-1Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ test("function inference 1", () => {
6868
test("args method", () => {
6969
const t1 = z.function();
7070
type t1 = (typeof t1)["_input"];
71-
expectTypeOf<t1>().toEqualTypeOf<(...args_1: unknown[]) => unknown>();
71+
expectTypeOf<t1>().toEqualTypeOf<(...args_1: never[]) => unknown>();
7272

7373
const t2args = z.tuple([z.string()], z.unknown());
7474

@@ -81,6 +81,14 @@ test("args method", () => {
8181
expectTypeOf<t3>().toEqualTypeOf<(arg: string, ...args_1: unknown[]) => boolean>();
8282
});
8383

84+
test("contravariance", () => {
85+
const fn = z.function().implement((_a: string, _b: number) => {
86+
return new Date();
87+
});
88+
89+
expectTypeOf(fn).toEqualTypeOf<(a: string, b: number) => Date>();
90+
});
91+
8492
const args2 = z.tuple([
8593
z.object({
8694
f1: z.number(),
Collapse file

‎packages/zod/src/v4/core/function.ts‎

Copy file name to clipboardExpand all lines: packages/zod/src/v4/core/function.ts
+45-29Lines changed: 45 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,40 +12,47 @@ import type * as util from "./util.js";
1212
////////// //////////
1313
//////////////////////////////////////////
1414
//////////////////////////////////////////
15-
export interface $ZodFunctionDef /* extends schemas.$ZodTypeDef */ {
15+
export interface $ZodFunctionDef<
16+
In extends $ZodFunctionIn = $ZodFunctionIn,
17+
Out extends $ZodFunctionOut = $ZodFunctionOut,
18+
> {
1619
type: "function";
17-
input: $ZodFunctionArgs | null;
18-
output: schemas.$ZodType | null;
20+
input: In;
21+
output: Out;
1922
}
2023

2124
export type $ZodFunctionArgs = schemas.$ZodType<unknown[], unknown[]>;
25+
export type $ZodFunctionIn = $ZodFunctionArgs | null;
26+
export type $ZodFunctionOut = schemas.$ZodType | null;
2227

23-
export type $InferInnerFunctionType<Args extends $ZodFunctionArgs, Returns extends schemas.$ZodType> = (
24-
...args: Args["_zod"]["output"]
25-
) => Returns["_zod"]["input"];
28+
export type $InferInnerFunctionType<Args extends $ZodFunctionIn, Returns extends $ZodFunctionOut> = (
29+
...args: null extends Args ? never[] : NonNullable<Args>["_zod"]["output"]
30+
) => null extends Returns ? unknown : NonNullable<Returns>["_zod"]["input"];
2631

27-
export type $InferInnerFunctionTypeAsync<Args extends $ZodFunctionArgs, Returns extends schemas.$ZodType> = (
28-
...args: Args["_zod"]["output"]
29-
) => util.MaybeAsync<Returns["_zod"]["input"]>;
32+
export type $InferInnerFunctionTypeAsync<Args extends $ZodFunctionIn, Returns extends $ZodFunctionOut> = (
33+
...args: null extends Args ? never[] : NonNullable<Args>["_zod"]["output"]
34+
) => null extends Returns ? unknown : util.MaybeAsync<NonNullable<Returns>["_zod"]["input"]>;
3035

31-
export type $InferOuterFunctionType<Args extends $ZodFunctionArgs, Returns extends schemas.$ZodType> = (
32-
...args: Args["_zod"]["input"]
33-
) => Returns["_zod"]["output"];
36+
export type $InferOuterFunctionType<Args extends $ZodFunctionIn, Returns extends $ZodFunctionOut> = (
37+
...args: null extends Args ? never[] : NonNullable<Args>["_zod"]["input"]
38+
) => null extends Returns ? unknown : NonNullable<Returns>["_zod"]["output"];
3439

35-
export type $InferOuterFunctionTypeAsync<Args extends $ZodFunctionArgs, Returns extends schemas.$ZodType> = (
36-
...args: Args["_zod"]["input"]
37-
) => util.MaybeAsync<Returns["_zod"]["output"]>;
40+
export type $InferOuterFunctionTypeAsync<Args extends $ZodFunctionIn, Returns extends $ZodFunctionOut> = (
41+
...args: null extends Args ? never[] : NonNullable<Args>["_zod"]["input"]
42+
) => null extends Returns ? unknown : util.MaybeAsync<NonNullable<Returns>["_zod"]["output"]>;
3843

3944
export class $ZodFunction<
40-
Args extends $ZodFunctionArgs = $ZodFunctionArgs,
41-
Returns extends schemas.$ZodType = schemas.$ZodType,
45+
Args extends $ZodFunctionIn = $ZodFunctionIn,
46+
Returns extends $ZodFunctionOut = $ZodFunctionOut,
4247
> {
43-
_def: $ZodFunctionDef;
48+
_def: $ZodFunctionDef<Args, Returns>;
49+
def: $ZodFunctionDef<Args, Returns>;
4450
_input!: $InferInnerFunctionType<Args, Returns>;
4551
_output!: $InferOuterFunctionType<Args, Returns>;
4652

47-
constructor(def: $ZodFunctionDef) {
53+
constructor(def: $ZodFunctionDef<Args, Returns>) {
4854
this._def = def;
55+
this.def = def;
4956
}
5057

5158
implement<F extends $InferInnerFunctionType<Args, Returns>>(
@@ -59,7 +66,7 @@ export class $ZodFunction<
5966
if (!Array.isArray(parsedArgs)) {
6067
throw new Error("Invalid arguments schema: not an array or tuple schema.");
6168
}
62-
const output = func(...parsedArgs);
69+
const output = func(...(parsedArgs as any));
6370
return this._def.output ? parse(this._def.output, output, undefined, { callee: impl }) : output;
6471
}) as any;
6572
return impl;
@@ -77,17 +84,17 @@ export class $ZodFunction<
7784
if (!Array.isArray(parsedArgs)) {
7885
throw new Error("Invalid arguments schema: not an array or tuple schema.");
7986
}
80-
const output = await func(...parsedArgs);
87+
const output = await func(...(parsedArgs as any));
8188
return this._def.output ? parseAsync(this._def.output, output, undefined, { callee: impl }) : output;
8289
}) as any;
8390
return impl;
8491
}
8592

86-
input<const Items extends util.TupleItems, const Rest extends schemas.$ZodType | null = null>(
93+
input<const Items extends util.TupleItems, const Rest extends $ZodFunctionOut = null>(
8794
args: Items,
8895
rest?: Rest
8996
): $ZodFunction<schemas.$ZodTuple<Items, Rest>, Returns>;
90-
input<NewArgs extends $ZodFunctionArgs>(args: NewArgs): $ZodFunction<NewArgs, Returns>;
97+
input<NewArgs extends $ZodFunctionIn>(args: NewArgs): $ZodFunction<NewArgs, Returns>;
9198
input(...args: any[]): $ZodFunction<any, Returns> {
9299
if (Array.isArray(args[0])) {
93100
return new $ZodFunction({
@@ -116,19 +123,28 @@ export class $ZodFunction<
116123
}
117124
}
118125

119-
export interface $ZodFunctionParams<I extends $ZodFunctionArgs, O extends schemas.$ZodType> {
126+
export interface $ZodFunctionParams<I extends $ZodFunctionIn, O extends schemas.$ZodType> {
120127
input?: I;
121128
output?: O;
122129
}
123130

124131
function _function(): $ZodFunction;
132+
function _function<const In extends Array<schemas.$ZodType> = Array<schemas.$ZodType>>(params: {
133+
input: In;
134+
}): $ZodFunction<$ZodTuple<In, null>, null>;
135+
function _function<const In extends $ZodFunctionIn = $ZodFunctionIn>(params: {
136+
input: In;
137+
}): $ZodFunction<In, null>;
138+
function _function<const Out extends $ZodFunctionOut = $ZodFunctionOut>(params: {
139+
output: Out;
140+
}): $ZodFunction<null, Out>;
125141
function _function<
126-
const In extends Array<schemas.$ZodType> = Array<schemas.$ZodType>,
142+
In extends $ZodFunctionIn = $ZodFunctionIn,
127143
Out extends schemas.$ZodType = schemas.$ZodType,
128-
>(params?: { input?: In; output?: Out }): $ZodFunction<$ZodTuple<In, null>, Out>;
129-
function _function<In extends $ZodFunctionArgs = $ZodFunctionArgs, Out extends schemas.$ZodType = schemas.$ZodType>(
130-
params?: $ZodFunctionParams<In, Out>
131-
): $ZodFunction<In, Out>;
144+
>(params?: {
145+
input: In;
146+
output: Out;
147+
}): $ZodFunction<In, Out>;
132148
function _function(params?: {
133149
output?: schemas.$ZodType;
134150
input?: $ZodFunctionArgs | Array<schemas.$ZodType>;
Collapse file

‎play.ts‎

Copy file name to clipboard
+9-16Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,13 @@
11
import * as z from "zod/v4";
22

3-
z;
3+
export const a = z.object({
4+
asdf: z.iso.datetime(),
5+
});
46

5-
const result = z.toJSONSchema(z.date(), {
6-
unrepresentable: "any",
7-
override: (ctx) => {
8-
const def = ctx.zodSchema._zod.def;
9-
if (def.type === "date") {
10-
ctx.jsonSchema.type = "string";
11-
ctx.jsonSchema.format = "date-time";
12-
}
13-
},
7+
const fn = z.function({
8+
// input: z.tuple([z.string()], z.number()),
9+
output: z.string(),
1410
});
15-
/* => {
16-
type: 'string',
17-
format: 'date-time',
18-
'$schema': 'https://json-schema.org/draft/2020-12/schema'
19-
} */
20-
console.dir(result, { depth: null });
11+
12+
fn.def.output;
13+
fn.def.input;
Collapse file

‎tsconfig.json‎

Copy file name to clipboardExpand all lines: tsconfig.json
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"extends": "./.configs/tsconfig.base.json",
33
"compilerOptions": {
44
"rootDir": ".",
5-
"noEmit": true
5+
"declaration": true
66
},
77
"exclude": ["packages/docs"]
88
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.