Skip to main content
Module

x/zod/__tests__/recursive.test.ts

TypeScript-first schema validation with static type inference
Extremely Popular
Go to Latest
File
// @ts-ignore TS6133import { expect } from "https://deno.land/x/expect@v0.2.6/mod.ts";const test = Deno.test;
import { z } from "../index.ts";
interface Category { name: string; subcategories: Category[];}
const testCategory: Category = { name: "I", subcategories: [ { name: "A", subcategories: [ { name: "1", subcategories: [ { name: "a", subcategories: [], }, ], }, ], }, ],};
test("recursion with z.late.object", () => { const Category: z.ZodType<Category> = z.late.object(() => ({ name: z.string(), subcategories: z.array(Category), })); Category.parse(testCategory);});
test("recursion with z.lazy", () => { const Category: z.ZodType<Category> = z.lazy(() => z.object({ name: z.string(), subcategories: z.array(Category), }) ); Category.parse(testCategory);});
test("schema getter", () => { z.lazy(() => z.string()).schema.parse("asdf");});
type LinkedList = null | { value: number; next: LinkedList };
const linkedListExample = { value: 1, next: { value: 2, next: { value: 3, next: { value: 4, next: null, }, }, },};
test("recursion involving union type", () => { const LinkedListSchema: z.ZodType<LinkedList> = z.lazy(() => z.union([ z.null(), z.object({ value: z.number(), next: LinkedListSchema, }), ]) ); LinkedListSchema.parse(linkedListExample);});
// interface A {// val: number;// b: B;// }
// interface B {// val: number;// a: A;// }
// const A: z.ZodType<A> = z.late.object(() => ({// val: z.number(),// b: B,// }));
// const B: z.ZodType<B> = z.late.object(() => ({// val: z.number(),// a: A,// }));
// const Alazy: z.ZodType<A> = z.lazy(() => z.object({// val: z.number(),// b: B,// }));
// const Blazy: z.ZodType<B> = z.lazy(() => z.object({// val: z.number(),// a: A,// }));
// const a: any = { val: 1 };// const b: any = { val: 2 };// a.b = b;// b.a = a;
// test('valid check', () => {// A.parse(a);// B.parse(b);// });
// test("valid check lazy", () => {// A.parse({val:1, b:});// B.parse(b);// });
// test('masking check', () => {// const FragmentOnA = z// .object({// val: z.number(),// b: z// .object({// val: z.number(),// a: z// .object({// val: z.number(),// })// .nonstrict(),// })// .nonstrict(),// })// .nonstrict();
// const fragment = FragmentOnA.parse(a);// fragment;// });
// test('invalid check', () => {// expect(() => A.parse({} as any)).toThrow();// });
// test('schema getter', () => {// (A as z.ZodLazy<any>).schema;// });
// test("self recursion with cyclical data", () => {// interface Category {// name: string;// subcategories: Category[];// }
// const Category: z.ZodType<Category> = z.late.object(() => ({// name: z.string(),// subcategories: z.array(Category),// }));
// const untypedCategory: any = {// name: "Category A",// };// // creating a cycle// untypedCategory.subcategories = [untypedCategory];// Category.parse(untypedCategory);// });
// test("self recursion with base type", () => {// const BaseCategory = z.object({// name: z.string(),// });// type BaseCategory = z.infer<typeof BaseCategory>;
// type Category = BaseCategory & { subcategories: Category[] };
// const Category: z.ZodType<Category> = z.late// .object(() => ({// subcategories: z.array(Category),// }))// .extend({// name: z.string(),// });
// const untypedCategory: any = {// name: "Category A",// };// // creating a cycle// untypedCategory.subcategories = [untypedCategory];// Category.parse(untypedCategory); // parses successfully// });