Skip to content

Commit d9076dd

Browse files
authored
fix: handling non-identifier index access type (#289)
* fix: handle single quotes in index access type * fix: handle element access expression in index access type
1 parent fe7e6ae commit d9076dd

File tree

2 files changed

+43
-5
lines changed

2 files changed

+43
-5
lines changed

src/core/generateZodSchema.test.ts

+26
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,32 @@ describe("generateZodSchema", () => {
583583
`);
584584
});
585585

586+
it("should deal with index access type using single quote (1st level)", () => {
587+
const source = `export type SupermanName = {
588+
name?: Superman['name']
589+
}`;
590+
591+
expect(generate(source)).toMatchInlineSnapshot(`
592+
"export const supermanNameSchema = z.object({
593+
name: supermanSchema.shape.name.optional()
594+
});"
595+
`);
596+
});
597+
598+
it("should deal with index access type with element access expression (1st level)", () => {
599+
const source = `export type SupermanName = {
600+
firstName: Superman["name.firstName"]
601+
lastName: Superman["name-lastName"]
602+
}`;
603+
604+
expect(generate(source)).toMatchInlineSnapshot(`
605+
"export const supermanNameSchema = z.object({
606+
firstName: supermanSchema.shape["name.firstName"],
607+
lastName: supermanSchema.shape["name-lastName"]
608+
});"
609+
`);
610+
});
611+
586612
it("should deal with record with a union as key", () => {
587613
const source = `
588614
export type AvailablePower = Record<Power, boolean>;

src/core/generateZodSchema.ts

+17-5
Original file line numberDiff line numberDiff line change
@@ -1390,9 +1390,11 @@ function buildSchemaReference(
13901390
getDependencyName: Required<GenerateZodSchemaProps>["getDependencyName"];
13911391
},
13921392
path = ""
1393-
): ts.PropertyAccessExpression | ts.Identifier {
1393+
): ts.PropertyAccessExpression | ts.Identifier | ts.ElementAccessExpression {
13941394
const indexTypeText = node.indexType.getText(sourceFile);
1395-
const { indexTypeName, type: indexTypeType } = /^"\w+"$/.exec(indexTypeText)
1395+
const { indexTypeName, type: indexTypeType } = /^['"]([^'"]+)['"]$/.exec(
1396+
indexTypeText
1397+
)
13961398
? { type: "string" as const, indexTypeName: indexTypeText.slice(1, -1) }
13971399
: { type: "number" as const, indexTypeName: indexTypeText };
13981400

@@ -1496,9 +1498,19 @@ function buildSchemaReference(
14961498
node.objectType.typeName.getText(sourceFile)
14971499
);
14981500
dependencies.push(dependencyName);
1499-
return f.createPropertyAccessExpression(
1500-
f.createIdentifier(dependencyName),
1501-
f.createIdentifier(`shape.${indexTypeName}.${path}`.slice(0, -1))
1501+
1502+
if (/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(indexTypeName)) {
1503+
return f.createPropertyAccessExpression(
1504+
f.createIdentifier(dependencyName),
1505+
f.createIdentifier(`shape.${indexTypeName}.${path}`.slice(0, -1))
1506+
);
1507+
}
1508+
return f.createElementAccessExpression(
1509+
f.createPropertyAccessExpression(
1510+
f.createIdentifier(dependencyName),
1511+
f.createIdentifier("shape")
1512+
),
1513+
f.createStringLiteral(indexTypeName)
15021514
);
15031515
}
15041516

0 commit comments

Comments
 (0)