cloudflare / cloudflare/chanfana

Obj and Arr lose type inference

Open Beginner friendly
#287 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
766
Forks
70
Avg merge
25m
Merged PRs (30d)
4

Description

### **Description**

When using the helper functions `Obj` and `Arr` as drop-in replacements for `z.object` and `z.array`, TypeScript type inference becomes too loose — resulting in `any`-like behavior.

This causes loss of type safety in downstream schema usage.

---

### **Steps to Reproduce**

```ts
import { Obj, Arr, Str } from 'chanfana'
import z from 'zod'

const schema1 = z.object({ items: z.array(Str()) })
const schema2 = Obj({ items: Arr(Str()) })

type A = z.infer // { items: string[] }
type B = z.infer // { [x: string]: any } (loose typing ❌)
```

---

### **Expected Behavior**

`Obj` and `Arr` should preserve generic type inference identical to `z.object` and `z.array`.

---

### **Actual Behavior**

The return types are too generic (`ZodObject` / `ZodArray`), causing type information to be lost.

---

### **Proposed Fix**

Use generics to propagate type information (https://github.com/cloudflare/chanfana/commit/8a0e226436d9bd830e0c2b9ac93077fd185c8766):

```diff
-export function Arr(innerType: any, params?: ParameterType): z.ZodArray {
+export function Arr(innerType: T, params?: ParameterType): z.ZodArray {
return convertParams(legacyTypeIntoZod(innerType).array(), params);
}

-export function Obj(fields: object, params?: ParameterType): z.ZodObject {
+export function Obj(fields: T, params?: ParameterType): z.ZodObject {
return convertParams(legacyTypeIntoZod(z.object(fields)), params);
}
```

---

### **Result**

After applying this patch, type inference now matches native Zod behavior:

```ts
type B = z.infer // ✅ { items: string[] }
```

Contributor guide

Open the contributing guide

Research direction

Start at the Arr and Obj helper definitions and inspect how they call legacyTypeIntoZod and convertParams. Reproduce the issue with the TypeScript examples in the report, then verify that z.infer preserves the item type like the native Zod schema.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, backend-api-design
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.