UNPKG

zod

Version:

TypeScript-first schema declaration and validation library with static type inference

177 lines (158 loc) 6.29 kB
import { _array, _tuple, _unknown } from "./api.js"; import type * as core from "./core.js"; import { parse, parseAsync } from "./parse.js"; import * as schemas from "./schemas.js"; import { $ZodTuple } from "./schemas.js"; import type * as util from "./util.js"; ////////////////////////////////////////// ////////////////////////////////////////// ////////// ////////// ////////// $ZodFunction ////////// ////////// ////////// ////////////////////////////////////////// ////////////////////////////////////////// export interface $ZodFunctionDef< In extends $ZodFunctionIn = $ZodFunctionIn, Out extends $ZodFunctionOut = $ZodFunctionOut, > { type: "function"; input: In; output: Out; } export type $ZodFunctionArgs = schemas.$ZodType<unknown[], unknown[]>; export type $ZodFunctionIn = $ZodFunctionArgs; export type $ZodFunctionOut = schemas.$ZodType; export type $InferInnerFunctionType<Args extends $ZodFunctionIn, Returns extends $ZodFunctionOut> = ( ...args: $ZodFunctionIn extends Args ? never[] : core.output<Args> ) => core.input<Returns>; export type $InferInnerFunctionTypeAsync<Args extends $ZodFunctionIn, Returns extends $ZodFunctionOut> = ( ...args: $ZodFunctionIn extends Args ? never[] : core.output<Args> ) => util.MaybeAsync<core.input<Returns>>; export type $InferOuterFunctionType<Args extends $ZodFunctionIn, Returns extends $ZodFunctionOut> = ( ...args: $ZodFunctionIn extends Args ? never[] : core.input<Args> ) => core.output<Returns>; export type $InferOuterFunctionTypeAsync<Args extends $ZodFunctionIn, Returns extends $ZodFunctionOut> = ( ...args: $ZodFunctionIn extends Args ? never[] : core.input<Args> ) => util.MaybeAsync<core.output<Returns>>; export class $ZodFunction< Args extends $ZodFunctionIn = $ZodFunctionIn, Returns extends $ZodFunctionOut = $ZodFunctionOut, > { def: $ZodFunctionDef<Args, Returns>; /** @deprecated */ _def!: $ZodFunctionDef<Args, Returns>; _input!: $InferInnerFunctionType<Args, Returns>; _output!: $InferOuterFunctionType<Args, Returns>; constructor(def: $ZodFunctionDef<Args, Returns>) { this._def = def; this.def = def; } implement<F extends $InferInnerFunctionType<Args, Returns>>( func: F ): // allow for return type inference ( ...args: Parameters<this["_output"]> ) => ReturnType<F> extends ReturnType<this["_output"]> ? ReturnType<F> : ReturnType<this["_output"]> { if (typeof func !== "function") { throw new Error("implement() must be called with a function"); } const impl = ((...args: any[]) => { const parsedArgs = this._def.input ? parse(this._def.input, args, undefined, { callee: impl }) : args; if (!Array.isArray(parsedArgs)) { throw new Error("Invalid arguments schema: not an array or tuple schema."); } const output = func(...(parsedArgs as any)); return this._def.output ? parse(this._def.output, output, undefined, { callee: impl }) : output; }) as any; return impl; } implementAsync<F extends $InferInnerFunctionTypeAsync<Args, Returns>>( func: F ): F extends $InferOuterFunctionTypeAsync<Args, Returns> ? F : $InferOuterFunctionTypeAsync<Args, Returns> { if (typeof func !== "function") { throw new Error("implement() must be called with a function"); } const impl = (async (...args: any[]) => { const parsedArgs = this._def.input ? await parseAsync(this._def.input, args, undefined, { callee: impl }) : args; if (!Array.isArray(parsedArgs)) { throw new Error("Invalid arguments schema: not an array or tuple schema."); } const output = await func(...(parsedArgs as any)); return this._def.output ? parseAsync(this._def.output, output, undefined, { callee: impl }) : output; }) as any; return impl; } input<const Items extends util.TupleItems, const Rest extends $ZodFunctionOut = $ZodFunctionOut>( args: Items, rest?: Rest ): $ZodFunction<schemas.$ZodTuple<Items, Rest>, Returns>; input<NewArgs extends $ZodFunctionIn>(args: NewArgs): $ZodFunction<NewArgs, Returns>; input(...args: any[]): $ZodFunction<any, Returns> { const F: any = this.constructor; if (Array.isArray(args[0])) { return new F({ type: "function", input: new $ZodTuple({ type: "tuple", items: args[0], rest: args[1], }), output: this._def.output, }); } return new F({ type: "function", input: args[0], output: this._def.output, }); } output<NewReturns extends schemas.$ZodType>(output: NewReturns): $ZodFunction<Args, NewReturns> { const F: any = this.constructor; return new F({ type: "function", input: this._def.input, output, }); } } export interface $ZodFunctionParams<I extends $ZodFunctionIn, O extends schemas.$ZodType> { input?: I; output?: O; } function _function(): $ZodFunction; function _function<const In extends Array<schemas.$ZodType> = Array<schemas.$ZodType>>(params: { input: In; }): $ZodFunction<$ZodTuple<In, null>, $ZodFunctionOut>; function _function< const In extends Array<schemas.$ZodType> = Array<schemas.$ZodType>, const Out extends $ZodFunctionOut = $ZodFunctionOut, >(params: { input: In; output: Out; }): $ZodFunction<$ZodTuple<In, null>, Out>; function _function<const In extends $ZodFunctionIn = $ZodFunctionIn>(params: { input: In; }): $ZodFunction<In, $ZodFunctionOut>; function _function<const Out extends $ZodFunctionOut = $ZodFunctionOut>(params: { output: Out; }): $ZodFunction<$ZodFunctionIn, Out>; function _function< In extends $ZodFunctionIn = $ZodFunctionIn, Out extends schemas.$ZodType = schemas.$ZodType, >(params?: { input: In; output: Out; }): $ZodFunction<In, Out>; function _function(params?: { output?: schemas.$ZodType; input?: $ZodFunctionArgs | Array<schemas.$ZodType>; }): any { return new $ZodFunction({ type: "function", input: Array.isArray(params?.input) ? _tuple(schemas.$ZodTuple, params?.input as any) : (params?.input ?? _array(schemas.$ZodArray, _unknown(schemas.$ZodUnknown))), output: params?.output ?? _unknown(schemas.$ZodUnknown), }); } export { _function as function };