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

Issue:
Types introduced in import, along with array abbreviations (PS: CustomType []), cause the output .zod content to be empty.
## Bug description

Types introduced in import, along with array abbreviations (PS: CustomType []), cause the output .zod content to be empty.

### Input

```ts
import { ReferenceLine } from './internal/reference-line';

export interface Global {
    referenceLines?: ReferenceLine[] | null;
}

```

### Expected output

```ts
// Generated by ts-to-zod
import { z } from "zod";

import { referenceLineSchema } from "./internal/reference-line.zod";

export const globalSchema = z.object({
  referenceLines: z.array(referenceLineSchema).optional().nullable(),
});
```

### Actual output

```ts
// Generated by ts-to-zod
import { z } from "zod";

import { referenceLineSchema } from "./internal/reference-line.zod";
```

**Versions**

- Typescript: `v5.4.5`
- Zod: `v3.22.4`


Pull request description:
fix: handling imported types as array in union and referenced in tuples
# Why

Fixes #228 

Patch:
diff --git a/src/utils/traverseTypes.ts b/src/utils/traverseTypes.ts
index b74b3a2..6caacee 100644
--- a/src/utils/traverseTypes.ts
+++ b/src/utils/traverseTypes.ts
@@ -54,15 +54,13 @@ export function getExtractedTypeNames(
       handleTypeNode(typeNode.elementType);
     } else if (ts.isTypeLiteralNode(typeNode)) {
       typeNode.forEachChild(visitorExtract);
+    } else if (ts.isTupleTypeNode(typeNode)) {
+      typeNode.elements.forEach(handleTypeNode);
     } else if (
       ts.isIntersectionTypeNode(typeNode) ||
       ts.isUnionTypeNode(typeNode)
     ) {
-      typeNode.types.forEach((childNode: ts.TypeNode) => {
-        if (ts.isTypeReferenceNode(childNode)) {
-          handleTypeReferenceNode(childNode);
-        } else childNode.forEachChild(visitorExtract);
-      });
+      typeNode.types.forEach(handleTypeNode);
     }
   };
 


Test patch:
diff --git a/src/utils/traverseTypes.test.ts b/src/utils/traverseTypes.test.ts
index 7b91b5f..7b0dca8 100644
--- a/src/utils/traverseTypes.test.ts
+++ b/src/utils/traverseTypes.test.ts
@@ -114,6 +114,16 @@ describe("traverseTypes", () => {
       expect(result).toEqual(["Superhero", "Person"]);
     });
 
+    it("should extract type referenced as array in union property", () => {
+      const source = `
+            export interface Superhero {
+                sidekicks: Person[] | null,
+            }`;
+
+      const result = extractNames(source);
+      expect(result).toEqual(["Superhero", "Person"]);
+    });
+
     it("should extract nested type reference", () => {
       const source = `
           export interface Superhero {
@@ -182,6 +192,17 @@ describe("traverseTypes", () => {
       expect(result).toEqual(["Person", "SuperHero", "Villain"]);
     });
 
+    it("should extract types from Tuple", () => {
+      const source = `
+        export interface Person {
+            id: number,
+            t: [SuperHero, Villain]
+        }`;
+
+      const result = extractNames(source);
+      expect(result).toEqual(["Person", "SuperHero", "Villain"]);
+    });
+
     it("should extract type from type alias", () => {
       const source = `
         export type Person = SuperHero `;
@@ -293,6 +314,30 @@ describe("traverseTypes", () => {
       const result = extractNames(source);
       expect(result).toEqual(["Person", "Villain", "SuperHero"]);
     });
+
+    it("should extract types from a very weird type definition (testing edge cases)", () => {
+      const source = `
+        export type Person = {
+          type: (SuperHero | Person2) & (SuperHero2 & Villain2) | SuperHero3[] | Villain3
+          tupleProp: [A | B, C & D]
+        } | Villain`;
+
+      const result = extractNames(source);
+      expect(result).toEqual([
+        "Person",
+        "SuperHero",
+        "Person2",
+        "SuperHero2",
+        "Villain2",
+        "SuperHero3",
+        "Villain3",
+        "A",
+        "B",
+        "C",
+        "D",
+        "Villain",
+      ]);
+    });
   });
 });