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

Issue:
Schema for picked and nullabled type is not nullable
## Bug description

When picking a subtype and marking it nullable, the generated zod schema loses the nullable attribute

### Input

```ts
export type foo = {
        bar: number;
}

export type bla = foo['bar'] | null
```

### Expected output

```ts
export const blaSchema = fooSchema.shape.bar.nullable();
```

### Actual output

```ts
export const blaSchema = fooSchema.shape.bar
```

**Versions**

- Typescript: `4.9.3`
- Zod: `3.21.4`


Pull request:
fix: handling optional & nullable in IndedexedAccessType
Fixes #129 

Patch:
diff --git a/src/core/generateZodSchema.ts b/src/core/generateZodSchema.ts
index 37500e3..821b30d 100644
--- a/src/core/generateZodSchema.ts
+++ b/src/core/generateZodSchema.ts
@@ -845,12 +845,15 @@ function buildZodPrimitive({
   }
 
   if (ts.isIndexedAccessTypeNode(typeNode)) {
-    return buildSchemaReference({
-      node: typeNode,
-      getDependencyName,
-      sourceFile,
-      dependencies,
-    });
+    return withZodProperties(
+      buildSchemaReference({
+        node: typeNode,
+        getDependencyName,
+        sourceFile,
+        dependencies,
+      }),
+      zodProperties
+    );
   }
 
   switch (typeNode.kind) {


Test patch:
diff --git a/src/core/generateZodSchema.test.ts b/src/core/generateZodSchema.test.ts
index 7649987..293897c 100644
--- a/src/core/generateZodSchema.test.ts
+++ b/src/core/generateZodSchema.test.ts
@@ -556,6 +556,26 @@ describe("generateZodSchema", () => {
     );
   });
 
+  it("should deal with nullable index access type (1st level)", () => {
+    const source = `export type SupermanName = Superman["name"] | null`;
+
+    expect(generate(source)).toMatchInlineSnapshot(
+      `"export const supermanNameSchema = supermanSchema.shape.name.nullable();"`
+    );
+  });
+
+  it("should deal with optional index access type (1st level)", () => {
+    const source = `export type SupermanName = {
+      name?: Superman["name"]
+    }`;
+
+    expect(generate(source)).toMatchInlineSnapshot(`
+      "export const supermanNameSchema = z.object({
+          name: supermanSchema.shape.name.optional()
+      });"
+      `);
+  });
+
   it("should deal with record with a union as key", () => {
     const source = `
     export type AvailablePower = Record<Power, boolean>;