cloudflare / cloudflare/chanfana
Obj and Arr lose type inference
- 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
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