Skip to content

Commit

Permalink
fix: [#1693] Tuple with empty items (#1712)
Browse files Browse the repository at this point in the history
* Add testcase - tuple as sparse array

* Destructure array to make .map() work properly - ZodTuple

* Make tuple as sparse array test more clear

* Add testcase - array as sparse array

* Destructure array to make .map() work properly - ZodArray
  • Loading branch information
metuan committed Dec 24, 2022
1 parent 49770ac commit bcaaf73
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 4 deletions.
6 changes: 6 additions & 0 deletions deno/lib/__tests__/array.test.ts
Expand Up @@ -64,3 +64,9 @@ test("continue parsing despite array size error", () => {
expect(result.error.issues.length).toEqual(2);
}
});

test("parse should fail given sparse array", () => {
const schema = z.array(z.string()).nonempty().min(1).max(3);

expect(() => schema.parse(new Array(3))).toThrow();
});
4 changes: 4 additions & 0 deletions deno/lib/__tests__/tuple.test.ts
Expand Up @@ -89,6 +89,10 @@ test("tuple with rest schema", () => {
util.assertEqual<t1, [string, number, ...boolean[]]>(true);
});

test("parse should fail given sparse array as tuple", () => {
expect(() => testTuple.parse(new Array(3))).toThrow();
});

// test('tuple with optional elements', () => {
// const result = z
// .tuple([z.string(), z.number().optional()])
Expand Down
2 changes: 1 addition & 1 deletion deno/lib/types.ts
Expand Up @@ -2851,7 +2851,7 @@ export class ZodTuple<
status.dirty();
}

const items = (ctx.data as any[])
const items = ([...ctx.data] as any[])
.map((item, itemIndex) => {
const schema = this._def.items[itemIndex] || this._def.rest;
if (!schema) return null as any as SyncParseReturnType<any>;
Expand Down
6 changes: 6 additions & 0 deletions src/__tests__/array.test.ts
Expand Up @@ -63,3 +63,9 @@ test("continue parsing despite array size error", () => {
expect(result.error.issues.length).toEqual(2);
}
});

test("parse should fail given sparse array", () => {
const schema = z.array(z.string()).nonempty().min(1).max(3);

expect(() => schema.parse(new Array(3))).toThrow();
});
4 changes: 4 additions & 0 deletions src/__tests__/tuple.test.ts
Expand Up @@ -88,6 +88,10 @@ test("tuple with rest schema", () => {
util.assertEqual<t1, [string, number, ...boolean[]]>(true);
});

test("parse should fail given sparse array as tuple", () => {
expect(() => testTuple.parse(new Array(3))).toThrow();
});

// test('tuple with optional elements', () => {
// const result = z
// .tuple([z.string(), z.number().optional()])
Expand Down
6 changes: 3 additions & 3 deletions src/types.ts
Expand Up @@ -1713,7 +1713,7 @@ export class ZodArray<

if (ctx.common.async) {
return Promise.all(
(ctx.data as any[]).map((item, i) => {
([...ctx.data] as any[]).map((item, i) => {
return def.type._parseAsync(
new ParseInputLazyPath(ctx, item, ctx.path, i)
);
Expand All @@ -1723,7 +1723,7 @@ export class ZodArray<
});
}

const result = (ctx.data as any[]).map((item, i) => {
const result = ([...ctx.data] as any[]).map((item, i) => {
return def.type._parseSync(
new ParseInputLazyPath(ctx, item, ctx.path, i)
);
Expand Down Expand Up @@ -2851,7 +2851,7 @@ export class ZodTuple<
status.dirty();
}

const items = (ctx.data as any[])
const items = ([...ctx.data] as any[])
.map((item, itemIndex) => {
const schema = this._def.items[itemIndex] || this._def.rest;
if (!schema) return null as any as SyncParseReturnType<any>;
Expand Down

0 comments on commit bcaaf73

Please sign in to comment.