Skip to content

Commit

Permalink
Fix Go To Definition for inferred merged object properties
Browse files Browse the repository at this point in the history
  • Loading branch information
bentefay committed May 5, 2022
1 parent fac389c commit 9b846c6
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 16 deletions.
6 changes: 4 additions & 2 deletions deno/lib/__tests__/languageServerFeatures.source.ts
Expand Up @@ -12,19 +12,20 @@ export const instanceOfTest: Test = {

export const TestMerge = z
.object({
f5: z.literal("literal").optional(),
f2: z.string().optional(),
})
.merge(Test);

export type TestMerge = z.infer<typeof TestMerge>;

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,
]);
Expand All @@ -33,6 +34,7 @@ export type TestUnion = z.infer<typeof TestUnion>;

export const instanceOfTestUnion: TestUnion = {
f1: 1,
f2: "string",
};

export const TestPartial = Test.partial();
Expand Down
52 changes: 49 additions & 3 deletions deno/lib/__tests__/languageServerFeatures.test.ts
Expand Up @@ -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");
Expand All @@ -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"
Expand All @@ -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"
Expand All @@ -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(
Expand Down
4 changes: 1 addition & 3 deletions deno/lib/types.ts
Expand Up @@ -1393,9 +1393,7 @@ export namespace objectUtil {
};
}

export type extendShape<A, B> = {
[k in Exclude<keyof A, keyof B>]: A[k];
} & { [k in keyof B]: B[k] };
export type extendShape<A, B> = Omit<A, keyof B> & B;

const AugmentFactory =
<Def extends ZodObjectDef>(def: Def) =>
Expand Down
6 changes: 4 additions & 2 deletions src/__tests__/languageServerFeatures.source.ts
Expand Up @@ -12,19 +12,20 @@ export const instanceOfTest: Test = {

export const TestMerge = z
.object({
f5: z.literal("literal").optional(),
f2: z.string().optional(),
})
.merge(Test);

export type TestMerge = z.infer<typeof TestMerge>;

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,
]);
Expand All @@ -33,6 +34,7 @@ export type TestUnion = z.infer<typeof TestUnion>;

export const instanceOfTestUnion: TestUnion = {
f1: 1,
f2: "string",
};

export const TestPartial = Test.partial();
Expand Down
52 changes: 49 additions & 3 deletions src/__tests__/languageServerFeatures.test.ts
Expand Up @@ -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");
Expand All @@ -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"
Expand All @@ -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"
Expand All @@ -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(
Expand Down
4 changes: 1 addition & 3 deletions src/types.ts
Expand Up @@ -1393,9 +1393,7 @@ export namespace objectUtil {
};
}

export type extendShape<A, B> = {
[k in Exclude<keyof A, keyof B>]: A[k];
} & { [k in keyof B]: B[k] };
export type extendShape<A, B> = Omit<A, keyof B> & B;

const AugmentFactory =
<Def extends ZodObjectDef>(def: Def) =>
Expand Down

0 comments on commit 9b846c6

Please sign in to comment.