Skip to content

Obj and Arr lose type inference #287

Description

@boobam22

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

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<typeof schema1> // { items: string[] }
type B = z.infer<typeof schema2> // { [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<any> / ZodArray<any>), causing type information to be lost.


Proposed Fix

Use generics to propagate type information (8a0e226):

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

-export function Obj(fields: object, params?: ParameterType): z.ZodObject<any> {
+export function Obj<T extends z.ZodRawShape>(fields: T, params?: ParameterType): z.ZodObject<T, 'strict'> {
   return convertParams(legacyTypeIntoZod(z.object(fields)), params);
 }

Result

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

type B = z.infer<typeof schema2> // ✅ { items: string[] }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions