Repository: fabien0102/ts-to-zod (ts)

Issue:
Error when referencing an imported type in an Index Signature Type
## Feature description

<!-- A clear and concise description of what the feature could be. -->
To support index signature type.

### Input

```ts
// typescript type or interface causing the output
export interface ResourceLink {
    /**
     * The link url.
     * @type {string}
     * @memberof ResourceLink
     */
    href: string;
    /**
     * The link method.
     * @type {string}
     * @memberof ResourceLink
     */
    method: string;
    /**
     * Additional data about the link.
     * @type {string}
     * @memberof ResourceLink
     */
    metadata?: string | null;
}

export interface AppDto {
    /**
     * The links.
     * @type {{ [key: string]: ResourceLink; }}
     * @memberof AppDto
     */
    links: {
        [key: string]: ResourceLink;
    };
}
```

### Output

```ts
// Expected Zod schemas
export const resourceLinkSchema = z.object({
  href: z.string(),
  method: z.string(),
  metadata: z.string().optional().nullable(),
});

export const appDtoSchema = z.object({
  links: z.record(resourceLinkSchema),
});
```


Pull request:
fix: correctly extract types from index signature declaration
# Why

Fixes #277 



Patch:
diff --git a/src/utils/traverseTypes.ts b/src/utils/traverseTypes.ts
index 853683d..1b99335 100644
--- a/src/utils/traverseTypes.ts
+++ b/src/utils/traverseTypes.ts
@@ -38,13 +38,13 @@ export function getReferencedTypeNames(
   referenceTypeNames.add({ name: node.name.text, partOfQualifiedName: false });
 
   const visitorExtract = (child: ts.Node) => {
-    if (!ts.isPropertySignature(child)) {
-      return;
-    }
-
-    const childNode = child as ts.PropertySignature;
-    if (childNode.type) {
-      handleTypeNode(childNode.type);
+    if (ts.isPropertySignature(child)) {
+      const childNode = child as ts.PropertySignature;
+      if (childNode.type) {
+        handleTypeNode(childNode.type);
+      }
+    } else if (ts.isIndexSignatureDeclaration(child) && child.type) {
+      handleTypeNode(child.type);
     }
   };
 


Test patch:
diff --git a/src/utils/traverseTypes.test.ts b/src/utils/traverseTypes.test.ts
index ba011a2..47d22bf 100644
--- a/src/utils/traverseTypes.test.ts
+++ b/src/utils/traverseTypes.test.ts
@@ -477,6 +477,18 @@ describe("traverseTypes", () => {
         { name: "Skill", partOfQualifiedName: false },
       ]);
     });
+
+    it("should extract type in index signature", () => {
+      const source = `export interface Hero {
+        powers: {[name: string] : Power}
+      }`;
+
+      const result = extractNames(source);
+      expect(result).toEqual([
+        { name: "Hero", partOfQualifiedName: false },
+        { name: "Power", partOfQualifiedName: false },
+      ]);
+    });
   });
 });