From 27663a97240a0b02f4b0b1942e98182c18d7b4be Mon Sep 17 00:00:00 2001 From: Ben Tefay Date: Thu, 5 May 2022 20:35:21 +1000 Subject: [PATCH 01/11] Increase test coverage for type inference of optional object properties --- deno/lib/__tests__/object.test.ts | 40 +++++++++++++++++++++++++++++++ src/__tests__/object.test.ts | 40 +++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/deno/lib/__tests__/object.test.ts b/deno/lib/__tests__/object.test.ts index fac2b9ffd..1dde59e42 100644 --- a/deno/lib/__tests__/object.test.ts +++ b/deno/lib/__tests__/object.test.ts @@ -216,6 +216,46 @@ test("test inferred merged type", async () => { f1; }); +test("inferred merged object type with optional properties", async () => { + const Merged = z + .object({ a: z.string(), b: z.string().optional() }) + .merge(z.object({ a: z.string().optional(), b: z.string() })); + type Merged = z.infer; + const f1: util.AssertEqual = true; + f1; +}); + +test("inferred unioned object type with optional properties", async () => { + const Unioned = z.union([ + z.object({ a: z.string(), b: z.string().optional() }), + z.object({ a: z.string().optional(), b: z.string() }), + ]); + type Unioned = z.infer; + const f1: util.AssertEqual< + Unioned, + { a: string; b?: string } | { a?: string; b: string } + > = true; + f1; +}); + +test("inferred partial object type with optional properties", async () => { + const Partial = z + .object({ a: z.string(), b: z.string().optional() }) + .partial(); + type Partial = z.infer; + const f1: util.AssertEqual = true; + f1; +}); + +test("inferred picked object type with optional properties", async () => { + const Picked = z + .object({ a: z.string(), b: z.string().optional() }) + .pick({ b: true }); + type Picked = z.infer; + const f1: util.AssertEqual = true; + f1; +}); + test("inferred type for unknown/any keys", () => { const myType = z.object({ anyOptional: z.any().optional(), diff --git a/src/__tests__/object.test.ts b/src/__tests__/object.test.ts index fc01e6397..22c1eb151 100644 --- a/src/__tests__/object.test.ts +++ b/src/__tests__/object.test.ts @@ -215,6 +215,46 @@ test("test inferred merged type", async () => { f1; }); +test("inferred merged object type with optional properties", async () => { + const Merged = z + .object({ a: z.string(), b: z.string().optional() }) + .merge(z.object({ a: z.string().optional(), b: z.string() })); + type Merged = z.infer; + const f1: util.AssertEqual = true; + f1; +}); + +test("inferred unioned object type with optional properties", async () => { + const Unioned = z.union([ + z.object({ a: z.string(), b: z.string().optional() }), + z.object({ a: z.string().optional(), b: z.string() }), + ]); + type Unioned = z.infer; + const f1: util.AssertEqual< + Unioned, + { a: string; b?: string } | { a?: string; b: string } + > = true; + f1; +}); + +test("inferred partial object type with optional properties", async () => { + const Partial = z + .object({ a: z.string(), b: z.string().optional() }) + .partial(); + type Partial = z.infer; + const f1: util.AssertEqual = true; + f1; +}); + +test("inferred picked object type with optional properties", async () => { + const Picked = z + .object({ a: z.string(), b: z.string().optional() }) + .pick({ b: true }); + type Picked = z.infer; + const f1: util.AssertEqual = true; + f1; +}); + test("inferred type for unknown/any keys", () => { const myType = z.object({ anyOptional: z.any().optional(), From 1c6d7ad1a9cfa1a257f0a2732a5faa81562ea55a Mon Sep 17 00:00:00 2001 From: Ben Tefay Date: Thu, 5 May 2022 20:36:12 +1000 Subject: [PATCH 02/11] Add test showing that Go To Definition is broken on object properties --- .../languageServerFeatures.source.ts | 46 +++++++ .../__tests__/languageServerFeatures.test.ts | 121 ++++++++++++++++++ package.json | 1 + .../languageServerFeatures.source.ts | 46 +++++++ src/__tests__/languageServerFeatures.test.ts | 120 +++++++++++++++++ yarn.lock | 61 ++++++++- 6 files changed, 389 insertions(+), 6 deletions(-) create mode 100644 deno/lib/__tests__/languageServerFeatures.source.ts create mode 100644 deno/lib/__tests__/languageServerFeatures.test.ts create mode 100644 src/__tests__/languageServerFeatures.source.ts create mode 100644 src/__tests__/languageServerFeatures.test.ts diff --git a/deno/lib/__tests__/languageServerFeatures.source.ts b/deno/lib/__tests__/languageServerFeatures.source.ts new file mode 100644 index 000000000..0153542cf --- /dev/null +++ b/deno/lib/__tests__/languageServerFeatures.source.ts @@ -0,0 +1,46 @@ +import * as z from "../index.ts"; + +export const Test = z.object({ + f1: z.number(), +}); + +export type Test = z.infer; + +export const instanceOfTest: Test = { + f1: 1, +}; + +export const TestMerge = z + .object({ + f5: z.literal("literal").optional(), + }) + .merge(Test); + +export type TestMerge = z.infer; + +export const instanceOfTestMerge: TestMerge = { + f1: 1, +}; + +export const TestUnion = z.union([ + z.object({ + f2: z.literal("literal").optional(), + }), + Test, +]); + +export type TestUnion = z.infer; + +export const instanceOfTestUnion: TestUnion = { + f1: 1, +}; + +export const TestPartial = Test.partial(); + +export type TestPartial = z.infer; + +export const instanceOfTestPartial: TestPartial = { + f1: 1, +}; + +export const filePath = __filename; diff --git a/deno/lib/__tests__/languageServerFeatures.test.ts b/deno/lib/__tests__/languageServerFeatures.test.ts new file mode 100644 index 000000000..658f7499d --- /dev/null +++ b/deno/lib/__tests__/languageServerFeatures.test.ts @@ -0,0 +1,121 @@ +// @ts-ignore TS6133 +import { expect } from "https://deno.land/x/expect@v0.2.6/mod.ts"; +const test = Deno.test; +import { filePath } from "./languageServerFeatures.source.ts"; +import { Project, Node, SyntaxKind } from "ts-morph"; +import path from "path"; + +// The following tool is helpful for understanding the TypeScript AST associated with these tests: +// https://ts-ast-viewer.com/ (just copy the contents of languageServerFeatures.source into the viewer) + +describe("Executing Go To Definition (and therefore Find Usages and Rename Refactoring) using an IDE works on inferred object properties", () => { + // Compile file developmentEnvironment.source + const project = new Project({ + tsConfigFilePath: path.join(__dirname, "..", "..", "tsconfig.json"), + skipAddingFilesFromTsConfig: true, + }); + const sourceFile = project.addSourceFileAtPath(filePath); + + test("works for objects", () => { + // Find usage of Test.f1 property + const instanceVariable = + sourceFile.getVariableDeclarationOrThrow("instanceOfTest"); + const propertyBeingAssigned = getPropertyBeingAssigned( + instanceVariable, + "f1" + ); + + // Find definition of Test.f1 property + const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; + const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( + SyntaxKind.VariableDeclaration + ); + + // Assert that find definition returned the Zod definition of Test + expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); + expect(parentOfProperty?.getName()).toEqual("Test"); + }); + + test("works for merged objects", () => { + // Find usage of TestMerge.f1 property + const instanceVariable = sourceFile.getVariableDeclarationOrThrow( + "instanceOfTestMerge" + ); + const propertyBeingAssigned = getPropertyBeingAssigned( + instanceVariable, + "f1" + ); + + // Find definition of TestMerge.f1 property + const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; + const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( + SyntaxKind.VariableDeclaration + ); + + // Assert that find definition returned the Zod definition of Test + expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); + expect(parentOfProperty?.getName()).toEqual("Test"); + }); + + test("works for unioned objects", () => { + // Find usage of TestUnion.f1 property + const instanceVariable = sourceFile.getVariableDeclarationOrThrow( + "instanceOfTestUnion" + ); + const propertyBeingAssigned = getPropertyBeingAssigned( + instanceVariable, + "f1" + ); + + // Find definition of TestUnion.f1 property + const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; + const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( + SyntaxKind.VariableDeclaration + ); + + // Assert that find definition returned the Zod definition of Test + expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); + expect(parentOfProperty?.getName()).toEqual("Test"); + }); + + test("works for partial objects", () => { + // Find usage of TestPartial.f1 property + const instanceVariable = sourceFile.getVariableDeclarationOrThrow( + "instanceOfTestPartial" + ); + const propertyBeingAssigned = getPropertyBeingAssigned( + instanceVariable, + "f1" + ); + + // Find definition of TestPartial.f1 property + const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; + const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( + SyntaxKind.VariableDeclaration + ); + + // Assert that find definition returned the Zod definition of Test + expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); + expect(parentOfProperty?.getName()).toEqual("Test"); + }); +}); + +const getPropertyBeingAssigned = (node: Node, name: string) => { + const propertyAssignment = node.forEachDescendant((descendent) => + Node.isPropertyAssignment(descendent) && descendent.getName() == name + ? descendent + : undefined + ); + + if (propertyAssignment == null) + fail(`Could not find property assignment with name ${name}`); + + const propertyLiteral = propertyAssignment.getFirstDescendantByKind( + SyntaxKind.Identifier + ); + + if (propertyLiteral == null) + fail(`Could not find property literal with name ${name}`); + + return propertyLiteral; +}; diff --git a/package.json b/package.json index e48cdc607..bd53b26e8 100644 --- a/package.json +++ b/package.json @@ -87,6 +87,7 @@ "pretty-quick": "^3.1.3", "rollup": "^2.70.1", "ts-jest": "^27.1.3", + "ts-morph": "^14.0.0", "ts-node": "^10.7.0", "tslib": "^2.3.1", "typescript": "^4.6.2" diff --git a/src/__tests__/languageServerFeatures.source.ts b/src/__tests__/languageServerFeatures.source.ts new file mode 100644 index 000000000..6de80ec49 --- /dev/null +++ b/src/__tests__/languageServerFeatures.source.ts @@ -0,0 +1,46 @@ +import * as z from "../index"; + +export const Test = z.object({ + f1: z.number(), +}); + +export type Test = z.infer; + +export const instanceOfTest: Test = { + f1: 1, +}; + +export const TestMerge = z + .object({ + f5: z.literal("literal").optional(), + }) + .merge(Test); + +export type TestMerge = z.infer; + +export const instanceOfTestMerge: TestMerge = { + f1: 1, +}; + +export const TestUnion = z.union([ + z.object({ + f2: z.literal("literal").optional(), + }), + Test, +]); + +export type TestUnion = z.infer; + +export const instanceOfTestUnion: TestUnion = { + f1: 1, +}; + +export const TestPartial = Test.partial(); + +export type TestPartial = z.infer; + +export const instanceOfTestPartial: TestPartial = { + f1: 1, +}; + +export const filePath = __filename; diff --git a/src/__tests__/languageServerFeatures.test.ts b/src/__tests__/languageServerFeatures.test.ts new file mode 100644 index 000000000..34249bb5e --- /dev/null +++ b/src/__tests__/languageServerFeatures.test.ts @@ -0,0 +1,120 @@ +// @ts-ignore TS6133 +import { expect, fit } from "@jest/globals"; +import { filePath } from "./languageServerFeatures.source"; +import { Project, Node, SyntaxKind } from "ts-morph"; +import path from "path"; + +// The following tool is helpful for understanding the TypeScript AST associated with these tests: +// https://ts-ast-viewer.com/ (just copy the contents of languageServerFeatures.source into the viewer) + +describe("Executing Go To Definition (and therefore Find Usages and Rename Refactoring) using an IDE works on inferred object properties", () => { + // Compile file developmentEnvironment.source + const project = new Project({ + tsConfigFilePath: path.join(__dirname, "..", "..", "tsconfig.json"), + skipAddingFilesFromTsConfig: true, + }); + const sourceFile = project.addSourceFileAtPath(filePath); + + test("works for objects", () => { + // Find usage of Test.f1 property + const instanceVariable = + sourceFile.getVariableDeclarationOrThrow("instanceOfTest"); + const propertyBeingAssigned = getPropertyBeingAssigned( + instanceVariable, + "f1" + ); + + // Find definition of Test.f1 property + const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; + const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( + SyntaxKind.VariableDeclaration + ); + + // Assert that find definition returned the Zod definition of Test + expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); + expect(parentOfProperty?.getName()).toEqual("Test"); + }); + + test("works for merged objects", () => { + // Find usage of TestMerge.f1 property + const instanceVariable = sourceFile.getVariableDeclarationOrThrow( + "instanceOfTestMerge" + ); + const propertyBeingAssigned = getPropertyBeingAssigned( + instanceVariable, + "f1" + ); + + // Find definition of TestMerge.f1 property + const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; + const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( + SyntaxKind.VariableDeclaration + ); + + // Assert that find definition returned the Zod definition of Test + expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); + expect(parentOfProperty?.getName()).toEqual("Test"); + }); + + test("works for unioned objects", () => { + // Find usage of TestUnion.f1 property + const instanceVariable = sourceFile.getVariableDeclarationOrThrow( + "instanceOfTestUnion" + ); + const propertyBeingAssigned = getPropertyBeingAssigned( + instanceVariable, + "f1" + ); + + // Find definition of TestUnion.f1 property + const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; + const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( + SyntaxKind.VariableDeclaration + ); + + // Assert that find definition returned the Zod definition of Test + expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); + expect(parentOfProperty?.getName()).toEqual("Test"); + }); + + test("works for partial objects", () => { + // Find usage of TestPartial.f1 property + const instanceVariable = sourceFile.getVariableDeclarationOrThrow( + "instanceOfTestPartial" + ); + const propertyBeingAssigned = getPropertyBeingAssigned( + instanceVariable, + "f1" + ); + + // Find definition of TestPartial.f1 property + const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; + const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( + SyntaxKind.VariableDeclaration + ); + + // Assert that find definition returned the Zod definition of Test + expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); + expect(parentOfProperty?.getName()).toEqual("Test"); + }); +}); + +const getPropertyBeingAssigned = (node: Node, name: string) => { + const propertyAssignment = node.forEachDescendant((descendent) => + Node.isPropertyAssignment(descendent) && descendent.getName() == name + ? descendent + : undefined + ); + + if (propertyAssignment == null) + fail(`Could not find property assignment with name ${name}`); + + const propertyLiteral = propertyAssignment.getFirstDescendantByKind( + SyntaxKind.Identifier + ); + + if (propertyLiteral == null) + fail(`Could not find property literal with name ${name}`); + + return propertyLiteral; +}; diff --git a/yarn.lock b/yarn.lock index fe52ffe54..b544138e5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -828,6 +828,16 @@ resolved "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz" integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== +"@ts-morph/common@~0.13.0": + version "0.13.0" + resolved "https://registry.yarnpkg.com/@ts-morph/common/-/common-0.13.0.tgz#77dea1565baaf002d1bc2c20e05d1fb3349008a9" + integrity sha512-fEJ6j7Cu8yiWjA4UmybOBH9Efgb/64ZTWuvCF4KysGu4xz8ettfyaqFt8WZ1btCxXsGZJjZ2/3svOF6rL+UFdQ== + dependencies: + fast-glob "^3.2.11" + minimatch "^5.0.1" + mkdirp "^1.0.4" + path-browserify "^1.0.1" + "@tsconfig/node10@^1.0.7": version "1.0.8" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9" @@ -1394,6 +1404,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + braces@^3.0.1, braces@~3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" @@ -1609,6 +1626,13 @@ co@^4.6.0: resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz" integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= +code-block-writer@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/code-block-writer/-/code-block-writer-11.0.0.tgz#5956fb186617f6740e2c3257757fea79315dd7d4" + integrity sha512-GEqWvEWWsOvER+g9keO4ohFoD3ymwyCnqY3hoTr7GZipYFwEhMHJw+TtV0rfgRhNImM6QWZGO2XYjlJVyYT62w== + dependencies: + tslib "2.3.1" + collect-v8-coverage@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz" @@ -2267,7 +2291,7 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.2.9: +fast-glob@^3.2.11, fast-glob@^3.2.9: version "3.2.11" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== @@ -3664,11 +3688,23 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" +minimatch@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" + integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.2.0, minimist@^1.2.5: version "1.2.5" resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== +mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + mri@^1.1.5: version "1.2.0" resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" @@ -3924,6 +3960,11 @@ parse5@6.0.1: resolved "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== +path-browserify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== + path-exists@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz" @@ -4633,6 +4674,14 @@ ts-jest@^27.1.3: semver "7.x" yargs-parser "20.x" +ts-morph@^14.0.0: + version "14.0.0" + resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-14.0.0.tgz#6bffb7e4584cf6a9aebce2066bf4258e1d03f9fa" + integrity sha512-tO8YQ1dP41fw8GVmeQAdNsD8roZi1JMqB7YwZrqU856DvmG5/710e41q2XauzTYrygH9XmMryaFeLo+kdCziyA== + dependencies: + "@ts-morph/common" "~0.13.0" + code-block-writer "^11.0.0" + ts-node@^10.7.0: version "10.7.0" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.7.0.tgz#35d503d0fab3e2baa672a0e94f4b40653c2463f5" @@ -4681,16 +4730,16 @@ tsconfig-paths@^3.9.0: minimist "^1.2.0" strip-bom "^3.0.0" +tslib@2.3.1, tslib@^2.1.0, tslib@^2.3.1: + version "2.3.1" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz" + integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== + tslib@^1.8.1, tslib@^1.9.0: version "1.14.1" resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.1.0, tslib@^2.3.1: - version "2.3.1" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz" - integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== - tsutils@^3.21.0: version "3.21.0" resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" From fac389cef56ef4d5ef829f8a513d12fdc8ce1ceb Mon Sep 17 00:00:00 2001 From: Ben Tefay Date: Thu, 5 May 2022 20:36:53 +1000 Subject: [PATCH 03/11] Fix Go To Definition for inferred object properties --- deno/lib/types.ts | 7 +------ src/types.ts | 7 +------ 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/deno/lib/types.ts b/deno/lib/types.ts index ee8bd6f27..6de7d3e73 100644 --- a/deno/lib/types.ts +++ b/deno/lib/types.ts @@ -1363,17 +1363,12 @@ export namespace objectUtil { [k in Exclude]: U[k]; } & V; - type optionalKeys = { - [k in keyof T]: undefined extends T[k] ? k : never; - }[keyof T]; - - // type requiredKeys = Exclude>; type requiredKeys = { [k in keyof T]: undefined extends T[k] ? never : k; }[keyof T]; export type addQuestionMarks = { - [k in optionalKeys]?: T[k]; + [k in keyof T]?: T[k]; } & { [k in requiredKeys]: T[k] }; export type identity = T; diff --git a/src/types.ts b/src/types.ts index 360e7fc49..05eee3536 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1363,17 +1363,12 @@ export namespace objectUtil { [k in Exclude]: U[k]; } & V; - type optionalKeys = { - [k in keyof T]: undefined extends T[k] ? k : never; - }[keyof T]; - - // type requiredKeys = Exclude>; type requiredKeys = { [k in keyof T]: undefined extends T[k] ? never : k; }[keyof T]; export type addQuestionMarks = { - [k in optionalKeys]?: T[k]; + [k in keyof T]?: T[k]; } & { [k in requiredKeys]: T[k] }; export type identity = T; From 9b846c65985ac1523b5dc92479b51502ea62fcc0 Mon Sep 17 00:00:00 2001 From: Ben Tefay Date: Thu, 5 May 2022 22:07:12 +1000 Subject: [PATCH 04/11] Fix Go To Definition for inferred merged object properties --- .../languageServerFeatures.source.ts | 6 ++- .../__tests__/languageServerFeatures.test.ts | 52 +++++++++++++++++-- deno/lib/types.ts | 4 +- .../languageServerFeatures.source.ts | 6 ++- src/__tests__/languageServerFeatures.test.ts | 52 +++++++++++++++++-- src/types.ts | 4 +- 6 files changed, 108 insertions(+), 16 deletions(-) diff --git a/deno/lib/__tests__/languageServerFeatures.source.ts b/deno/lib/__tests__/languageServerFeatures.source.ts index 0153542cf..55670263d 100644 --- a/deno/lib/__tests__/languageServerFeatures.source.ts +++ b/deno/lib/__tests__/languageServerFeatures.source.ts @@ -12,7 +12,7 @@ export const instanceOfTest: Test = { export const TestMerge = z .object({ - f5: z.literal("literal").optional(), + f2: z.string().optional(), }) .merge(Test); @@ -20,11 +20,12 @@ export type TestMerge = z.infer; export const instanceOfTestMerge: TestMerge = { f1: 1, + f2: "string", }; export const TestUnion = z.union([ z.object({ - f2: z.literal("literal").optional(), + f2: z.string().optional(), }), Test, ]); @@ -33,6 +34,7 @@ export type TestUnion = z.infer; export const instanceOfTestUnion: TestUnion = { f1: 1, + f2: "string", }; export const TestPartial = Test.partial(); diff --git a/deno/lib/__tests__/languageServerFeatures.test.ts b/deno/lib/__tests__/languageServerFeatures.test.ts index 658f7499d..f697f1668 100644 --- a/deno/lib/__tests__/languageServerFeatures.test.ts +++ b/deno/lib/__tests__/languageServerFeatures.test.ts @@ -16,7 +16,7 @@ describe("Executing Go To Definition (and therefore Find Usages and Rename Refac }); const sourceFile = project.addSourceFileAtPath(filePath); - test("works for objects", () => { + test("works for simple object properties", () => { // Find usage of Test.f1 property const instanceVariable = sourceFile.getVariableDeclarationOrThrow("instanceOfTest"); @@ -36,7 +36,7 @@ describe("Executing Go To Definition (and therefore Find Usages and Rename Refac expect(parentOfProperty?.getName()).toEqual("Test"); }); - test("works for merged objects", () => { + test("works for first merged object properties", () => { // Find usage of TestMerge.f1 property const instanceVariable = sourceFile.getVariableDeclarationOrThrow( "instanceOfTestMerge" @@ -57,7 +57,30 @@ describe("Executing Go To Definition (and therefore Find Usages and Rename Refac expect(parentOfProperty?.getName()).toEqual("Test"); }); - test("works for unioned objects", () => { + test("works for second merged object properties", () => { + // Find usage of TestMerge.f2 property + const instanceVariable = sourceFile.getVariableDeclarationOrThrow( + "instanceOfTestMerge" + ); + const propertyBeingAssigned = getPropertyBeingAssigned( + instanceVariable, + "f2" + ); + + // Find definition of TestMerge.f2 property + const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; + const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( + SyntaxKind.VariableDeclaration + ); + + // Assert that find definition returned the Zod definition of TestMerge + expect(definitionOfProperty?.getText()).toEqual( + "f2: z.string().optional()" + ); + expect(parentOfProperty?.getName()).toEqual("TestMerge"); + }); + + test("works for first unioned object properties", () => { // Find usage of TestUnion.f1 property const instanceVariable = sourceFile.getVariableDeclarationOrThrow( "instanceOfTestUnion" @@ -78,6 +101,29 @@ describe("Executing Go To Definition (and therefore Find Usages and Rename Refac expect(parentOfProperty?.getName()).toEqual("Test"); }); + test("works for second unioned object properties", () => { + // Find usage of TestUnion.f2 property + const instanceVariable = sourceFile.getVariableDeclarationOrThrow( + "instanceOfTestUnion" + ); + const propertyBeingAssigned = getPropertyBeingAssigned( + instanceVariable, + "f2" + ); + + // Find definition of TestUnion.f2 property + const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; + const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( + SyntaxKind.VariableDeclaration + ); + + // Assert that find definition returned the Zod definition of TestUnion + expect(definitionOfProperty?.getText()).toEqual( + "f2: z.string().optional()" + ); + expect(parentOfProperty?.getName()).toEqual("TestUnion"); + }); + test("works for partial objects", () => { // Find usage of TestPartial.f1 property const instanceVariable = sourceFile.getVariableDeclarationOrThrow( diff --git a/deno/lib/types.ts b/deno/lib/types.ts index 6de7d3e73..574da5f7b 100644 --- a/deno/lib/types.ts +++ b/deno/lib/types.ts @@ -1393,9 +1393,7 @@ export namespace objectUtil { }; } -export type extendShape = { - [k in Exclude]: A[k]; -} & { [k in keyof B]: B[k] }; +export type extendShape = Omit & B; const AugmentFactory = (def: Def) => diff --git a/src/__tests__/languageServerFeatures.source.ts b/src/__tests__/languageServerFeatures.source.ts index 6de80ec49..ea600cdec 100644 --- a/src/__tests__/languageServerFeatures.source.ts +++ b/src/__tests__/languageServerFeatures.source.ts @@ -12,7 +12,7 @@ export const instanceOfTest: Test = { export const TestMerge = z .object({ - f5: z.literal("literal").optional(), + f2: z.string().optional(), }) .merge(Test); @@ -20,11 +20,12 @@ export type TestMerge = z.infer; export const instanceOfTestMerge: TestMerge = { f1: 1, + f2: "string", }; export const TestUnion = z.union([ z.object({ - f2: z.literal("literal").optional(), + f2: z.string().optional(), }), Test, ]); @@ -33,6 +34,7 @@ export type TestUnion = z.infer; export const instanceOfTestUnion: TestUnion = { f1: 1, + f2: "string", }; export const TestPartial = Test.partial(); diff --git a/src/__tests__/languageServerFeatures.test.ts b/src/__tests__/languageServerFeatures.test.ts index 34249bb5e..096cbc946 100644 --- a/src/__tests__/languageServerFeatures.test.ts +++ b/src/__tests__/languageServerFeatures.test.ts @@ -15,7 +15,7 @@ describe("Executing Go To Definition (and therefore Find Usages and Rename Refac }); const sourceFile = project.addSourceFileAtPath(filePath); - test("works for objects", () => { + test("works for simple object properties", () => { // Find usage of Test.f1 property const instanceVariable = sourceFile.getVariableDeclarationOrThrow("instanceOfTest"); @@ -35,7 +35,7 @@ describe("Executing Go To Definition (and therefore Find Usages and Rename Refac expect(parentOfProperty?.getName()).toEqual("Test"); }); - test("works for merged objects", () => { + test("works for first merged object properties", () => { // Find usage of TestMerge.f1 property const instanceVariable = sourceFile.getVariableDeclarationOrThrow( "instanceOfTestMerge" @@ -56,7 +56,30 @@ describe("Executing Go To Definition (and therefore Find Usages and Rename Refac expect(parentOfProperty?.getName()).toEqual("Test"); }); - test("works for unioned objects", () => { + test("works for second merged object properties", () => { + // Find usage of TestMerge.f2 property + const instanceVariable = sourceFile.getVariableDeclarationOrThrow( + "instanceOfTestMerge" + ); + const propertyBeingAssigned = getPropertyBeingAssigned( + instanceVariable, + "f2" + ); + + // Find definition of TestMerge.f2 property + const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; + const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( + SyntaxKind.VariableDeclaration + ); + + // Assert that find definition returned the Zod definition of TestMerge + expect(definitionOfProperty?.getText()).toEqual( + "f2: z.string().optional()" + ); + expect(parentOfProperty?.getName()).toEqual("TestMerge"); + }); + + test("works for first unioned object properties", () => { // Find usage of TestUnion.f1 property const instanceVariable = sourceFile.getVariableDeclarationOrThrow( "instanceOfTestUnion" @@ -77,6 +100,29 @@ describe("Executing Go To Definition (and therefore Find Usages and Rename Refac expect(parentOfProperty?.getName()).toEqual("Test"); }); + test("works for second unioned object properties", () => { + // Find usage of TestUnion.f2 property + const instanceVariable = sourceFile.getVariableDeclarationOrThrow( + "instanceOfTestUnion" + ); + const propertyBeingAssigned = getPropertyBeingAssigned( + instanceVariable, + "f2" + ); + + // Find definition of TestUnion.f2 property + const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; + const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( + SyntaxKind.VariableDeclaration + ); + + // Assert that find definition returned the Zod definition of TestUnion + expect(definitionOfProperty?.getText()).toEqual( + "f2: z.string().optional()" + ); + expect(parentOfProperty?.getName()).toEqual("TestUnion"); + }); + test("works for partial objects", () => { // Find usage of TestPartial.f1 property const instanceVariable = sourceFile.getVariableDeclarationOrThrow( diff --git a/src/types.ts b/src/types.ts index 05eee3536..90e366b12 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1393,9 +1393,7 @@ export namespace objectUtil { }; } -export type extendShape = { - [k in Exclude]: A[k]; -} & { [k in keyof B]: B[k] }; +export type extendShape = Omit & B; const AugmentFactory = (def: Def) => From 18c375d5b1d2b144c5c8e0e7b6cd1aeea9135afc Mon Sep 17 00:00:00 2001 From: Ben Tefay Date: Fri, 6 May 2022 08:58:04 +1000 Subject: [PATCH 05/11] Improve languageServerFeatures test names --- deno/lib/__tests__/languageServerFeatures.source.ts | 11 ++++++++++- deno/lib/__tests__/languageServerFeatures.test.ts | 12 ++++++------ src/__tests__/languageServerFeatures.source.ts | 11 ++++++++++- src/__tests__/languageServerFeatures.test.ts | 12 ++++++------ 4 files changed, 32 insertions(+), 14 deletions(-) diff --git a/deno/lib/__tests__/languageServerFeatures.source.ts b/deno/lib/__tests__/languageServerFeatures.source.ts index 55670263d..741450a6f 100644 --- a/deno/lib/__tests__/languageServerFeatures.source.ts +++ b/deno/lib/__tests__/languageServerFeatures.source.ts @@ -1,5 +1,9 @@ import * as z from "../index.ts"; +export const filePath = __filename; + +// z.object() + export const Test = z.object({ f1: z.number(), }); @@ -10,6 +14,8 @@ export const instanceOfTest: Test = { f1: 1, }; +// z.object().merge() + export const TestMerge = z .object({ f2: z.string().optional(), @@ -23,6 +29,8 @@ export const instanceOfTestMerge: TestMerge = { f2: "string", }; +// z.union() + export const TestUnion = z.union([ z.object({ f2: z.string().optional(), @@ -37,6 +45,8 @@ export const instanceOfTestUnion: TestUnion = { f2: "string", }; +// z.object().partial() + export const TestPartial = Test.partial(); export type TestPartial = z.infer; @@ -45,4 +55,3 @@ export const instanceOfTestPartial: TestPartial = { f1: 1, }; -export const filePath = __filename; diff --git a/deno/lib/__tests__/languageServerFeatures.test.ts b/deno/lib/__tests__/languageServerFeatures.test.ts index f697f1668..a581a2a91 100644 --- a/deno/lib/__tests__/languageServerFeatures.test.ts +++ b/deno/lib/__tests__/languageServerFeatures.test.ts @@ -16,7 +16,7 @@ describe("Executing Go To Definition (and therefore Find Usages and Rename Refac }); const sourceFile = project.addSourceFileAtPath(filePath); - test("works for simple object properties", () => { + test("works for object properties inferred from z.object()", () => { // Find usage of Test.f1 property const instanceVariable = sourceFile.getVariableDeclarationOrThrow("instanceOfTest"); @@ -36,7 +36,7 @@ describe("Executing Go To Definition (and therefore Find Usages and Rename Refac expect(parentOfProperty?.getName()).toEqual("Test"); }); - test("works for first merged object properties", () => { + test("works for first object properties inferred from z.object().merge()", () => { // Find usage of TestMerge.f1 property const instanceVariable = sourceFile.getVariableDeclarationOrThrow( "instanceOfTestMerge" @@ -57,7 +57,7 @@ describe("Executing Go To Definition (and therefore Find Usages and Rename Refac expect(parentOfProperty?.getName()).toEqual("Test"); }); - test("works for second merged object properties", () => { + test("works for second object properties inferred from z.object().merge()", () => { // Find usage of TestMerge.f2 property const instanceVariable = sourceFile.getVariableDeclarationOrThrow( "instanceOfTestMerge" @@ -80,7 +80,7 @@ describe("Executing Go To Definition (and therefore Find Usages and Rename Refac expect(parentOfProperty?.getName()).toEqual("TestMerge"); }); - test("works for first unioned object properties", () => { + test("works for first object properties inferred from z.union()", () => { // Find usage of TestUnion.f1 property const instanceVariable = sourceFile.getVariableDeclarationOrThrow( "instanceOfTestUnion" @@ -101,7 +101,7 @@ describe("Executing Go To Definition (and therefore Find Usages and Rename Refac expect(parentOfProperty?.getName()).toEqual("Test"); }); - test("works for second unioned object properties", () => { + test("works for second object properties inferred from z.union()", () => { // Find usage of TestUnion.f2 property const instanceVariable = sourceFile.getVariableDeclarationOrThrow( "instanceOfTestUnion" @@ -124,7 +124,7 @@ describe("Executing Go To Definition (and therefore Find Usages and Rename Refac expect(parentOfProperty?.getName()).toEqual("TestUnion"); }); - test("works for partial objects", () => { + test("works for object properties inferred from z.object().partial()", () => { // Find usage of TestPartial.f1 property const instanceVariable = sourceFile.getVariableDeclarationOrThrow( "instanceOfTestPartial" diff --git a/src/__tests__/languageServerFeatures.source.ts b/src/__tests__/languageServerFeatures.source.ts index ea600cdec..472a29418 100644 --- a/src/__tests__/languageServerFeatures.source.ts +++ b/src/__tests__/languageServerFeatures.source.ts @@ -1,5 +1,9 @@ import * as z from "../index"; +export const filePath = __filename; + +// z.object() + export const Test = z.object({ f1: z.number(), }); @@ -10,6 +14,8 @@ export const instanceOfTest: Test = { f1: 1, }; +// z.object().merge() + export const TestMerge = z .object({ f2: z.string().optional(), @@ -23,6 +29,8 @@ export const instanceOfTestMerge: TestMerge = { f2: "string", }; +// z.union() + export const TestUnion = z.union([ z.object({ f2: z.string().optional(), @@ -37,6 +45,8 @@ export const instanceOfTestUnion: TestUnion = { f2: "string", }; +// z.object().partial() + export const TestPartial = Test.partial(); export type TestPartial = z.infer; @@ -45,4 +55,3 @@ export const instanceOfTestPartial: TestPartial = { f1: 1, }; -export const filePath = __filename; diff --git a/src/__tests__/languageServerFeatures.test.ts b/src/__tests__/languageServerFeatures.test.ts index 096cbc946..b89f0fc83 100644 --- a/src/__tests__/languageServerFeatures.test.ts +++ b/src/__tests__/languageServerFeatures.test.ts @@ -15,7 +15,7 @@ describe("Executing Go To Definition (and therefore Find Usages and Rename Refac }); const sourceFile = project.addSourceFileAtPath(filePath); - test("works for simple object properties", () => { + test("works for object properties inferred from z.object()", () => { // Find usage of Test.f1 property const instanceVariable = sourceFile.getVariableDeclarationOrThrow("instanceOfTest"); @@ -35,7 +35,7 @@ describe("Executing Go To Definition (and therefore Find Usages and Rename Refac expect(parentOfProperty?.getName()).toEqual("Test"); }); - test("works for first merged object properties", () => { + test("works for first object properties inferred from z.object().merge()", () => { // Find usage of TestMerge.f1 property const instanceVariable = sourceFile.getVariableDeclarationOrThrow( "instanceOfTestMerge" @@ -56,7 +56,7 @@ describe("Executing Go To Definition (and therefore Find Usages and Rename Refac expect(parentOfProperty?.getName()).toEqual("Test"); }); - test("works for second merged object properties", () => { + test("works for second object properties inferred from z.object().merge()", () => { // Find usage of TestMerge.f2 property const instanceVariable = sourceFile.getVariableDeclarationOrThrow( "instanceOfTestMerge" @@ -79,7 +79,7 @@ describe("Executing Go To Definition (and therefore Find Usages and Rename Refac expect(parentOfProperty?.getName()).toEqual("TestMerge"); }); - test("works for first unioned object properties", () => { + test("works for first object properties inferred from z.union()", () => { // Find usage of TestUnion.f1 property const instanceVariable = sourceFile.getVariableDeclarationOrThrow( "instanceOfTestUnion" @@ -100,7 +100,7 @@ describe("Executing Go To Definition (and therefore Find Usages and Rename Refac expect(parentOfProperty?.getName()).toEqual("Test"); }); - test("works for second unioned object properties", () => { + test("works for second object properties inferred from z.union()", () => { // Find usage of TestUnion.f2 property const instanceVariable = sourceFile.getVariableDeclarationOrThrow( "instanceOfTestUnion" @@ -123,7 +123,7 @@ describe("Executing Go To Definition (and therefore Find Usages and Rename Refac expect(parentOfProperty?.getName()).toEqual("TestUnion"); }); - test("works for partial objects", () => { + test("works for object properties inferred from z.object().partial()", () => { // Find usage of TestPartial.f1 property const instanceVariable = sourceFile.getVariableDeclarationOrThrow( "instanceOfTestPartial" From 45f138ee43714bf486008cbb6639bcb4787e9ee7 Mon Sep 17 00:00:00 2001 From: Ben Tefay Date: Fri, 6 May 2022 08:58:20 +1000 Subject: [PATCH 06/11] Fix Go To Definition for inferred pick object properties --- .../languageServerFeatures.source.ts | 9 +++++++++ .../__tests__/languageServerFeatures.test.ts | 20 +++++++++++++++++++ deno/lib/types.ts | 6 +----- .../languageServerFeatures.source.ts | 9 +++++++++ src/__tests__/languageServerFeatures.test.ts | 20 +++++++++++++++++++ src/types.ts | 6 +----- 6 files changed, 60 insertions(+), 10 deletions(-) diff --git a/deno/lib/__tests__/languageServerFeatures.source.ts b/deno/lib/__tests__/languageServerFeatures.source.ts index 741450a6f..04f291ccd 100644 --- a/deno/lib/__tests__/languageServerFeatures.source.ts +++ b/deno/lib/__tests__/languageServerFeatures.source.ts @@ -55,3 +55,12 @@ export const instanceOfTestPartial: TestPartial = { f1: 1, }; +// z.object().pick() + +export const TestPick = TestMerge.pick({ f1: true }); + +export type TestPick = z.infer; + +export const instanceOfTestPick: TestPick = { + f1: 1, +}; diff --git a/deno/lib/__tests__/languageServerFeatures.test.ts b/deno/lib/__tests__/languageServerFeatures.test.ts index a581a2a91..b7902d023 100644 --- a/deno/lib/__tests__/languageServerFeatures.test.ts +++ b/deno/lib/__tests__/languageServerFeatures.test.ts @@ -144,6 +144,26 @@ describe("Executing Go To Definition (and therefore Find Usages and Rename Refac expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); expect(parentOfProperty?.getName()).toEqual("Test"); }); + + test("works for object properties inferred from z.object().pick()", () => { + // Find usage of TestPick.f1 property + const instanceVariable = + sourceFile.getVariableDeclarationOrThrow("instanceOfTestPick"); + const propertyBeingAssigned = getPropertyBeingAssigned( + instanceVariable, + "f1" + ); + + // Find definition of TestPick.f1 property + const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; + const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( + SyntaxKind.VariableDeclaration + ); + + // Assert that find definition returned the Zod definition of Test + expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); + expect(parentOfProperty?.getName()).toEqual("Test"); + }); }); const getPropertyBeingAssigned = (node: Node, name: string) => { diff --git a/deno/lib/types.ts b/deno/lib/types.ts index 574da5f7b..aa93d2541 100644 --- a/deno/lib/types.ts +++ b/deno/lib/types.ts @@ -1705,11 +1705,7 @@ export class ZodObject< pick( mask: Mask - ): ZodObject< - objectUtil.noNever<{ [k in keyof Mask]: k extends keyof T ? T[k] : never }>, - UnknownKeys, - Catchall - > { + ): ZodObject>, UnknownKeys, Catchall> { const shape: any = {}; util.objectKeys(mask).map((key) => { shape[key] = this.shape[key]; diff --git a/src/__tests__/languageServerFeatures.source.ts b/src/__tests__/languageServerFeatures.source.ts index 472a29418..a62628c47 100644 --- a/src/__tests__/languageServerFeatures.source.ts +++ b/src/__tests__/languageServerFeatures.source.ts @@ -55,3 +55,12 @@ export const instanceOfTestPartial: TestPartial = { f1: 1, }; +// z.object().pick() + +export const TestPick = TestMerge.pick({ f1: true }); + +export type TestPick = z.infer; + +export const instanceOfTestPick: TestPick = { + f1: 1, +}; diff --git a/src/__tests__/languageServerFeatures.test.ts b/src/__tests__/languageServerFeatures.test.ts index b89f0fc83..b27042040 100644 --- a/src/__tests__/languageServerFeatures.test.ts +++ b/src/__tests__/languageServerFeatures.test.ts @@ -143,6 +143,26 @@ describe("Executing Go To Definition (and therefore Find Usages and Rename Refac expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); expect(parentOfProperty?.getName()).toEqual("Test"); }); + + test("works for object properties inferred from z.object().pick()", () => { + // Find usage of TestPick.f1 property + const instanceVariable = + sourceFile.getVariableDeclarationOrThrow("instanceOfTestPick"); + const propertyBeingAssigned = getPropertyBeingAssigned( + instanceVariable, + "f1" + ); + + // Find definition of TestPick.f1 property + const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; + const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( + SyntaxKind.VariableDeclaration + ); + + // Assert that find definition returned the Zod definition of Test + expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); + expect(parentOfProperty?.getName()).toEqual("Test"); + }); }); const getPropertyBeingAssigned = (node: Node, name: string) => { diff --git a/src/types.ts b/src/types.ts index 90e366b12..e3c7e3040 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1705,11 +1705,7 @@ export class ZodObject< pick( mask: Mask - ): ZodObject< - objectUtil.noNever<{ [k in keyof Mask]: k extends keyof T ? T[k] : never }>, - UnknownKeys, - Catchall - > { + ): ZodObject>, UnknownKeys, Catchall> { const shape: any = {}; util.objectKeys(mask).map((key) => { shape[key] = this.shape[key]; From 325adc628562545efd89d56af26bf2cb4599594e Mon Sep 17 00:00:00 2001 From: Ben Tefay Date: Fri, 6 May 2022 09:05:26 +1000 Subject: [PATCH 07/11] Fix Go To Definition for inferred omit object properties --- .../languageServerFeatures.source.ts | 10 ++++++++++ .../__tests__/languageServerFeatures.test.ts | 20 +++++++++++++++++++ deno/lib/types.ts | 6 +----- .../languageServerFeatures.source.ts | 10 ++++++++++ src/__tests__/languageServerFeatures.test.ts | 20 +++++++++++++++++++ src/types.ts | 6 +----- 6 files changed, 62 insertions(+), 10 deletions(-) diff --git a/deno/lib/__tests__/languageServerFeatures.source.ts b/deno/lib/__tests__/languageServerFeatures.source.ts index 04f291ccd..b0105556c 100644 --- a/deno/lib/__tests__/languageServerFeatures.source.ts +++ b/deno/lib/__tests__/languageServerFeatures.source.ts @@ -64,3 +64,13 @@ export type TestPick = z.infer; export const instanceOfTestPick: TestPick = { f1: 1, }; + +// z.object().omit() + +export const TestOmit = TestMerge.omit({ f2: true }); + +export type TestOmit = z.infer; + +export const instanceOfTestOmit: TestOmit = { + f1: 1, +}; diff --git a/deno/lib/__tests__/languageServerFeatures.test.ts b/deno/lib/__tests__/languageServerFeatures.test.ts index b7902d023..dcc4e5fdd 100644 --- a/deno/lib/__tests__/languageServerFeatures.test.ts +++ b/deno/lib/__tests__/languageServerFeatures.test.ts @@ -164,6 +164,26 @@ describe("Executing Go To Definition (and therefore Find Usages and Rename Refac expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); expect(parentOfProperty?.getName()).toEqual("Test"); }); + + test("works for object properties inferred from z.object().omit()", () => { + // Find usage of TestOmit.f1 property + const instanceVariable = + sourceFile.getVariableDeclarationOrThrow("instanceOfTestOmit"); + const propertyBeingAssigned = getPropertyBeingAssigned( + instanceVariable, + "f1" + ); + + // Find definition of TestOmit.f1 property + const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; + const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( + SyntaxKind.VariableDeclaration + ); + + // Assert that find definition returned the Zod definition of Test + expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); + expect(parentOfProperty?.getName()).toEqual("Test"); + }); }); const getPropertyBeingAssigned = (node: Node, name: string) => { diff --git a/deno/lib/types.ts b/deno/lib/types.ts index aa93d2541..af05aa754 100644 --- a/deno/lib/types.ts +++ b/deno/lib/types.ts @@ -1718,11 +1718,7 @@ export class ZodObject< omit( mask: Mask - ): ZodObject< - objectUtil.noNever<{ [k in keyof T]: k extends keyof Mask ? never : T[k] }>, - UnknownKeys, - Catchall - > { + ): ZodObject, UnknownKeys, Catchall> { const shape: any = {}; util.objectKeys(this.shape).map((key) => { if (util.objectKeys(mask).indexOf(key) === -1) { diff --git a/src/__tests__/languageServerFeatures.source.ts b/src/__tests__/languageServerFeatures.source.ts index a62628c47..f2e99a0c5 100644 --- a/src/__tests__/languageServerFeatures.source.ts +++ b/src/__tests__/languageServerFeatures.source.ts @@ -64,3 +64,13 @@ export type TestPick = z.infer; export const instanceOfTestPick: TestPick = { f1: 1, }; + +// z.object().omit() + +export const TestOmit = TestMerge.omit({ f2: true }); + +export type TestOmit = z.infer; + +export const instanceOfTestOmit: TestOmit = { + f1: 1, +}; diff --git a/src/__tests__/languageServerFeatures.test.ts b/src/__tests__/languageServerFeatures.test.ts index b27042040..0d065f760 100644 --- a/src/__tests__/languageServerFeatures.test.ts +++ b/src/__tests__/languageServerFeatures.test.ts @@ -163,6 +163,26 @@ describe("Executing Go To Definition (and therefore Find Usages and Rename Refac expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); expect(parentOfProperty?.getName()).toEqual("Test"); }); + + test("works for object properties inferred from z.object().omit()", () => { + // Find usage of TestOmit.f1 property + const instanceVariable = + sourceFile.getVariableDeclarationOrThrow("instanceOfTestOmit"); + const propertyBeingAssigned = getPropertyBeingAssigned( + instanceVariable, + "f1" + ); + + // Find definition of TestOmit.f1 property + const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; + const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( + SyntaxKind.VariableDeclaration + ); + + // Assert that find definition returned the Zod definition of Test + expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); + expect(parentOfProperty?.getName()).toEqual("Test"); + }); }); const getPropertyBeingAssigned = (node: Node, name: string) => { diff --git a/src/types.ts b/src/types.ts index e3c7e3040..a9fba5da9 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1718,11 +1718,7 @@ export class ZodObject< omit( mask: Mask - ): ZodObject< - objectUtil.noNever<{ [k in keyof T]: k extends keyof Mask ? never : T[k] }>, - UnknownKeys, - Catchall - > { + ): ZodObject, UnknownKeys, Catchall> { const shape: any = {}; util.objectKeys(this.shape).map((key) => { if (util.objectKeys(mask).indexOf(key) === -1) { From 8a41316600de3a99b9aa0f2884da27735c82a347 Mon Sep 17 00:00:00 2001 From: Ben Tefay Date: Fri, 6 May 2022 09:33:05 +1000 Subject: [PATCH 08/11] Exclude languageServerFeatures tests from deno --- deno/build.mjs | 6 +- .../languageServerFeatures.source.ts | 76 ------- .../__tests__/languageServerFeatures.test.ts | 207 ------------------ 3 files changed, 5 insertions(+), 284 deletions(-) delete mode 100644 deno/lib/__tests__/languageServerFeatures.source.ts delete mode 100644 deno/lib/__tests__/languageServerFeatures.test.ts diff --git a/deno/build.mjs b/deno/build.mjs index 0c84533c7..dfb4ac192 100644 --- a/deno/build.mjs +++ b/deno/build.mjs @@ -23,7 +23,11 @@ const projectRoot = process.cwd(); const nodeSrcRoot = join(projectRoot, "src"); const denoLibRoot = join(projectRoot, "deno", "lib"); -const skipList = [join(nodeSrcRoot, "__tests__", "object-in-es5-env.test.ts")]; +const skipList = [ + join(nodeSrcRoot, "__tests__", "object-in-es5-env.test.ts"), + join(nodeSrcRoot, "__tests__", "languageServerFeatures.test.ts"), + join(nodeSrcRoot, "__tests__", "languageServerFeatures.source.ts"), +]; const walkAndBuild = (/** @type string */ dir) => { for (const entry of readdirSync(join(nodeSrcRoot, dir), { withFileTypes: true, diff --git a/deno/lib/__tests__/languageServerFeatures.source.ts b/deno/lib/__tests__/languageServerFeatures.source.ts deleted file mode 100644 index b0105556c..000000000 --- a/deno/lib/__tests__/languageServerFeatures.source.ts +++ /dev/null @@ -1,76 +0,0 @@ -import * as z from "../index.ts"; - -export const filePath = __filename; - -// z.object() - -export const Test = z.object({ - f1: z.number(), -}); - -export type Test = z.infer; - -export const instanceOfTest: Test = { - f1: 1, -}; - -// z.object().merge() - -export const TestMerge = z - .object({ - f2: z.string().optional(), - }) - .merge(Test); - -export type TestMerge = z.infer; - -export const instanceOfTestMerge: TestMerge = { - f1: 1, - f2: "string", -}; - -// z.union() - -export const TestUnion = z.union([ - z.object({ - f2: z.string().optional(), - }), - Test, -]); - -export type TestUnion = z.infer; - -export const instanceOfTestUnion: TestUnion = { - f1: 1, - f2: "string", -}; - -// z.object().partial() - -export const TestPartial = Test.partial(); - -export type TestPartial = z.infer; - -export const instanceOfTestPartial: TestPartial = { - f1: 1, -}; - -// z.object().pick() - -export const TestPick = TestMerge.pick({ f1: true }); - -export type TestPick = z.infer; - -export const instanceOfTestPick: TestPick = { - f1: 1, -}; - -// z.object().omit() - -export const TestOmit = TestMerge.omit({ f2: true }); - -export type TestOmit = z.infer; - -export const instanceOfTestOmit: TestOmit = { - f1: 1, -}; diff --git a/deno/lib/__tests__/languageServerFeatures.test.ts b/deno/lib/__tests__/languageServerFeatures.test.ts deleted file mode 100644 index dcc4e5fdd..000000000 --- a/deno/lib/__tests__/languageServerFeatures.test.ts +++ /dev/null @@ -1,207 +0,0 @@ -// @ts-ignore TS6133 -import { expect } from "https://deno.land/x/expect@v0.2.6/mod.ts"; -const test = Deno.test; -import { filePath } from "./languageServerFeatures.source.ts"; -import { Project, Node, SyntaxKind } from "ts-morph"; -import path from "path"; - -// The following tool is helpful for understanding the TypeScript AST associated with these tests: -// https://ts-ast-viewer.com/ (just copy the contents of languageServerFeatures.source into the viewer) - -describe("Executing Go To Definition (and therefore Find Usages and Rename Refactoring) using an IDE works on inferred object properties", () => { - // Compile file developmentEnvironment.source - const project = new Project({ - tsConfigFilePath: path.join(__dirname, "..", "..", "tsconfig.json"), - skipAddingFilesFromTsConfig: true, - }); - const sourceFile = project.addSourceFileAtPath(filePath); - - test("works for object properties inferred from z.object()", () => { - // Find usage of Test.f1 property - const instanceVariable = - sourceFile.getVariableDeclarationOrThrow("instanceOfTest"); - const propertyBeingAssigned = getPropertyBeingAssigned( - instanceVariable, - "f1" - ); - - // Find definition of Test.f1 property - const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; - const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( - SyntaxKind.VariableDeclaration - ); - - // Assert that find definition returned the Zod definition of Test - expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); - expect(parentOfProperty?.getName()).toEqual("Test"); - }); - - test("works for first object properties inferred from z.object().merge()", () => { - // Find usage of TestMerge.f1 property - const instanceVariable = sourceFile.getVariableDeclarationOrThrow( - "instanceOfTestMerge" - ); - const propertyBeingAssigned = getPropertyBeingAssigned( - instanceVariable, - "f1" - ); - - // Find definition of TestMerge.f1 property - const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; - const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( - SyntaxKind.VariableDeclaration - ); - - // Assert that find definition returned the Zod definition of Test - expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); - expect(parentOfProperty?.getName()).toEqual("Test"); - }); - - test("works for second object properties inferred from z.object().merge()", () => { - // Find usage of TestMerge.f2 property - const instanceVariable = sourceFile.getVariableDeclarationOrThrow( - "instanceOfTestMerge" - ); - const propertyBeingAssigned = getPropertyBeingAssigned( - instanceVariable, - "f2" - ); - - // Find definition of TestMerge.f2 property - const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; - const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( - SyntaxKind.VariableDeclaration - ); - - // Assert that find definition returned the Zod definition of TestMerge - expect(definitionOfProperty?.getText()).toEqual( - "f2: z.string().optional()" - ); - expect(parentOfProperty?.getName()).toEqual("TestMerge"); - }); - - test("works for first object properties inferred from z.union()", () => { - // Find usage of TestUnion.f1 property - const instanceVariable = sourceFile.getVariableDeclarationOrThrow( - "instanceOfTestUnion" - ); - const propertyBeingAssigned = getPropertyBeingAssigned( - instanceVariable, - "f1" - ); - - // Find definition of TestUnion.f1 property - const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; - const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( - SyntaxKind.VariableDeclaration - ); - - // Assert that find definition returned the Zod definition of Test - expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); - expect(parentOfProperty?.getName()).toEqual("Test"); - }); - - test("works for second object properties inferred from z.union()", () => { - // Find usage of TestUnion.f2 property - const instanceVariable = sourceFile.getVariableDeclarationOrThrow( - "instanceOfTestUnion" - ); - const propertyBeingAssigned = getPropertyBeingAssigned( - instanceVariable, - "f2" - ); - - // Find definition of TestUnion.f2 property - const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; - const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( - SyntaxKind.VariableDeclaration - ); - - // Assert that find definition returned the Zod definition of TestUnion - expect(definitionOfProperty?.getText()).toEqual( - "f2: z.string().optional()" - ); - expect(parentOfProperty?.getName()).toEqual("TestUnion"); - }); - - test("works for object properties inferred from z.object().partial()", () => { - // Find usage of TestPartial.f1 property - const instanceVariable = sourceFile.getVariableDeclarationOrThrow( - "instanceOfTestPartial" - ); - const propertyBeingAssigned = getPropertyBeingAssigned( - instanceVariable, - "f1" - ); - - // Find definition of TestPartial.f1 property - const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; - const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( - SyntaxKind.VariableDeclaration - ); - - // Assert that find definition returned the Zod definition of Test - expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); - expect(parentOfProperty?.getName()).toEqual("Test"); - }); - - test("works for object properties inferred from z.object().pick()", () => { - // Find usage of TestPick.f1 property - const instanceVariable = - sourceFile.getVariableDeclarationOrThrow("instanceOfTestPick"); - const propertyBeingAssigned = getPropertyBeingAssigned( - instanceVariable, - "f1" - ); - - // Find definition of TestPick.f1 property - const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; - const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( - SyntaxKind.VariableDeclaration - ); - - // Assert that find definition returned the Zod definition of Test - expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); - expect(parentOfProperty?.getName()).toEqual("Test"); - }); - - test("works for object properties inferred from z.object().omit()", () => { - // Find usage of TestOmit.f1 property - const instanceVariable = - sourceFile.getVariableDeclarationOrThrow("instanceOfTestOmit"); - const propertyBeingAssigned = getPropertyBeingAssigned( - instanceVariable, - "f1" - ); - - // Find definition of TestOmit.f1 property - const definitionOfProperty = propertyBeingAssigned?.getDefinitionNodes()[0]; - const parentOfProperty = definitionOfProperty?.getFirstAncestorByKind( - SyntaxKind.VariableDeclaration - ); - - // Assert that find definition returned the Zod definition of Test - expect(definitionOfProperty?.getText()).toEqual("f1: z.number()"); - expect(parentOfProperty?.getName()).toEqual("Test"); - }); -}); - -const getPropertyBeingAssigned = (node: Node, name: string) => { - const propertyAssignment = node.forEachDescendant((descendent) => - Node.isPropertyAssignment(descendent) && descendent.getName() == name - ? descendent - : undefined - ); - - if (propertyAssignment == null) - fail(`Could not find property assignment with name ${name}`); - - const propertyLiteral = propertyAssignment.getFirstDescendantByKind( - SyntaxKind.Identifier - ); - - if (propertyLiteral == null) - fail(`Could not find property literal with name ${name}`); - - return propertyLiteral; -}; From 63edb1ca4871bfbb262df7f062d3f6bf1dda8713 Mon Sep 17 00:00:00 2001 From: Colin McDonnell Date: Thu, 5 May 2022 19:07:43 -0700 Subject: [PATCH 09/11] Fix keyof issue --- deno/lib/__tests__/object.test.ts | 12 ++++++++++++ deno/lib/types.ts | 2 +- package.json | 1 + src/__tests__/object.test.ts | 12 ++++++++++++ src/types.ts | 2 +- yarn.lock | 5 +++++ 6 files changed, 32 insertions(+), 2 deletions(-) diff --git a/deno/lib/__tests__/object.test.ts b/deno/lib/__tests__/object.test.ts index 1dde59e42..fdba95fda 100644 --- a/deno/lib/__tests__/object.test.ts +++ b/deno/lib/__tests__/object.test.ts @@ -1,6 +1,7 @@ // @ts-ignore TS6133 import { expect } from "https://deno.land/x/expect@v0.2.6/mod.ts"; const test = Deno.test; +import * as tc from "conditional-type-checks"; import { util } from "../helpers/util.ts"; import * as z from "../index.ts"; @@ -348,3 +349,14 @@ test("constructor key", () => { }) ).toThrow(); }); + +test("constructor key", () => { + const Example = z.object({ + prop: z.string(), + opt: z.number().optional(), + arr: z.string().array(), + }); + + type Example = z.infer; + tc.assert>(true); +}); diff --git a/deno/lib/types.ts b/deno/lib/types.ts index af05aa754..a8a3754fd 100644 --- a/deno/lib/types.ts +++ b/deno/lib/types.ts @@ -1363,7 +1363,7 @@ export namespace objectUtil { [k in Exclude]: U[k]; } & V; - type requiredKeys = { + export type requiredKeys = { [k in keyof T]: undefined extends T[k] ? never : k; }[keyof T]; diff --git a/package.json b/package.json index bd53b26e8..583a3cdac 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "@typescript-eslint/eslint-plugin": "^5.15.0", "@typescript-eslint/parser": "^5.15.0", "benchmark": "^2.1.4", + "conditional-type-checks": "^1.0.5", "dependency-cruiser": "^9.19.0", "eslint": "^8.11.0", "eslint-config-prettier": "^8.5.0", diff --git a/src/__tests__/object.test.ts b/src/__tests__/object.test.ts index 22c1eb151..d006aee98 100644 --- a/src/__tests__/object.test.ts +++ b/src/__tests__/object.test.ts @@ -1,5 +1,6 @@ // @ts-ignore TS6133 import { expect, test } from "@jest/globals"; +import * as tc from "conditional-type-checks"; import { util } from "../helpers/util"; import * as z from "../index"; @@ -347,3 +348,14 @@ test("constructor key", () => { }) ).toThrow(); }); + +test("constructor key", () => { + const Example = z.object({ + prop: z.string(), + opt: z.number().optional(), + arr: z.string().array(), + }); + + type Example = z.infer; + tc.assert>(true); +}); diff --git a/src/types.ts b/src/types.ts index a9fba5da9..877cda9d3 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1363,7 +1363,7 @@ export namespace objectUtil { [k in Exclude]: U[k]; } & V; - type requiredKeys = { + export type requiredKeys = { [k in keyof T]: undefined extends T[k] ? never : k; }[keyof T]; diff --git a/yarn.lock b/yarn.lock index b544138e5..dde6a7fbe 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1689,6 +1689,11 @@ concat-map@0.0.1: resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= +conditional-type-checks@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/conditional-type-checks/-/conditional-type-checks-1.0.5.tgz#310ecd13c46c3963fbe9a2f8f93511d88cdcc973" + integrity sha512-DkfkvmjXVe4ye4llJ1JADtO3dNvqqcQM08cA9BhNt9Oe8pyRW8X1CZyBg9Qst05bDV9BJM01KLmnFh78NcJgNg== + configstore@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz" From 44e74207a52d15c3153de8ff8c41fd3c412839c7 Mon Sep 17 00:00:00 2001 From: Colin McDonnell Date: Thu, 5 May 2022 19:08:20 -0700 Subject: [PATCH 10/11] 3.14.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 583a3cdac..66a01525f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zod", - "version": "3.14.4", + "version": "3.14.5", "description": "TypeScript-first schema declaration and validation library with static type inference", "main": "./lib/index.js", "types": "./index.d.ts", From 39dc37780830ba2144a17acbf8d21ce8bb0847c2 Mon Sep 17 00:00:00 2001 From: Colin McDonnell Date: Thu, 5 May 2022 19:16:14 -0700 Subject: [PATCH 11/11] Remove tc dep --- deno/lib/__tests__/object.test.ts | 4 ++-- package.json | 1 - src/__tests__/object.test.ts | 4 ++-- yarn.lock | 5 ----- 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/deno/lib/__tests__/object.test.ts b/deno/lib/__tests__/object.test.ts index fdba95fda..75a5c1237 100644 --- a/deno/lib/__tests__/object.test.ts +++ b/deno/lib/__tests__/object.test.ts @@ -1,7 +1,6 @@ // @ts-ignore TS6133 import { expect } from "https://deno.land/x/expect@v0.2.6/mod.ts"; const test = Deno.test; -import * as tc from "conditional-type-checks"; import { util } from "../helpers/util.ts"; import * as z from "../index.ts"; @@ -358,5 +357,6 @@ test("constructor key", () => { }); type Example = z.infer; - tc.assert>(true); + const f1: util.AssertEqual = true; + f1; }); diff --git a/package.json b/package.json index 66a01525f..1a650649b 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,6 @@ "@typescript-eslint/eslint-plugin": "^5.15.0", "@typescript-eslint/parser": "^5.15.0", "benchmark": "^2.1.4", - "conditional-type-checks": "^1.0.5", "dependency-cruiser": "^9.19.0", "eslint": "^8.11.0", "eslint-config-prettier": "^8.5.0", diff --git a/src/__tests__/object.test.ts b/src/__tests__/object.test.ts index d006aee98..100d7a633 100644 --- a/src/__tests__/object.test.ts +++ b/src/__tests__/object.test.ts @@ -1,6 +1,5 @@ // @ts-ignore TS6133 import { expect, test } from "@jest/globals"; -import * as tc from "conditional-type-checks"; import { util } from "../helpers/util"; import * as z from "../index"; @@ -357,5 +356,6 @@ test("constructor key", () => { }); type Example = z.infer; - tc.assert>(true); + const f1: util.AssertEqual = true; + f1; }); diff --git a/yarn.lock b/yarn.lock index dde6a7fbe..b544138e5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1689,11 +1689,6 @@ concat-map@0.0.1: resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -conditional-type-checks@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/conditional-type-checks/-/conditional-type-checks-1.0.5.tgz#310ecd13c46c3963fbe9a2f8f93511d88cdcc973" - integrity sha512-DkfkvmjXVe4ye4llJ1JADtO3dNvqqcQM08cA9BhNt9Oe8pyRW8X1CZyBg9Qst05bDV9BJM01KLmnFh78NcJgNg== - configstore@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz"