From f59df396529055404eca5300d12e1765bb157c65 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Mon, 21 Mar 2022 09:31:48 -0400 Subject: [PATCH] Faster paths --- src/types.ts | 73 +++++++++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/src/types.ts b/src/types.ts index ae1cc77b4..a3ad5ee1f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -16,6 +16,7 @@ import { ParseParams, ParseReturnType, ParseStatus, + ParsePath, SyncParseReturnType, ZodParsedType, } from "./helpers/parseUtil"; @@ -76,6 +77,27 @@ export interface ZodTypeDef { description?: string; } +class ParseInputLazyPath implements ParseInput { + parent: ParseContext; + data: any; + _path: ParsePath; + _key: string | number; + constructor( + parent: ParseContext, + value: any, + path: ParsePath, + key: string | number + ) { + this.parent = parent; + this.data = value; + this._path = path; + this._key = key; + } + get path() { + return [...this._path, this._key]; + } +} + const handleResult = ( ctx: ParseContext, result: SyncParseReturnType @@ -1289,11 +1311,9 @@ export class ZodArray< if (ctx.common.async) { return Promise.all( (ctx.data as any[]).map((item, i) => { - return def.type._parseAsync({ - parent: ctx, - path: [...ctx.path, i], - data: item, - }); + return def.type._parseAsync( + new ParseInputLazyPath(ctx, item, ctx.path, i) + ); }) ).then((result) => { return ParseStatus.mergeArray(status, result); @@ -1301,11 +1321,9 @@ export class ZodArray< } const result = (ctx.data as any[]).map((item, i) => { - return def.type._parseSync({ - parent: ctx, - path: [...ctx.path, i], - data: item, - }); + return def.type._parseSync( + new ParseInputLazyPath(ctx, item, ctx.path, i) + ); }); return ParseStatus.mergeArray(status, result); @@ -1505,6 +1523,7 @@ function deepPartialify(schema: ZodTypeAny): any { return schema; } } + export class ZodObject< T extends ZodRawShape, UnknownKeys extends UnknownKeysParam = "strip", @@ -1552,11 +1571,9 @@ export class ZodObject< const value = ctx.data[key]; pairs.push({ key: { status: "valid", value: key }, - value: keyValidator._parse({ - parent: ctx, - data: value, - path: [...ctx.path, key], - }), + value: keyValidator._parse( + new ParseInputLazyPath(ctx, value, ctx.path, key) + ), alwaysSet: key in ctx.data, }); } @@ -1592,7 +1609,7 @@ export class ZodObject< pairs.push({ key: { status: "valid", value: key }, value: catchall._parse( - { parent: ctx, path: [...ctx.path, key], data: value } //, ctx.child(key), value, getParsedType(value) + new ParseInputLazyPath(ctx, value, ctx.path, key) //, ctx.child(key), value, getParsedType(value) ), alwaysSet: key in ctx.data, }); @@ -2368,11 +2385,9 @@ export class ZodTuple< .map((item, itemIndex) => { const schema = this._def.items[itemIndex] || this._def.rest; if (!schema) return null as any as SyncParseReturnType; - return schema._parse({ - data: item, - path: [...ctx.path, itemIndex], - parent: ctx, - }); + return schema._parse( + new ParseInputLazyPath(ctx, item, ctx.path, itemIndex) + ); }) .filter((x) => !!x); // filter nulls @@ -2468,16 +2483,10 @@ export class ZodRecord< for (const key in ctx.data) { pairs.push({ - key: keyType._parse({ - data: key, - path: [...ctx.path, key], - parent: ctx, - }), - value: valueType._parse({ - data: ctx.data[key], - path: [...ctx.path, key], - parent: ctx, - }), + key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, key)), + value: valueType._parse( + new ParseInputLazyPath(ctx, ctx.data[key], ctx.path, key) + ), }); } @@ -2698,7 +2707,7 @@ export class ZodSet extends ZodType< } const elements = [...(ctx.data as Set).values()].map((item, i) => - valueType._parse({ data: item, path: [...ctx.path, i], parent: ctx }) + valueType._parse(new ParseInputLazyPath(ctx, item, ctx.path, i)) ); if (ctx.common.async) {