Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type error when combining catchall and array #3136

Closed
chaoran-chen opened this issue Jan 14, 2024 · 3 comments
Closed

Type error when combining catchall and array #3136

chaoran-chen opened this issue Jan 14, 2024 · 3 comments
Labels
bug-confirmed Bug report that is confirmed

Comments

@chaoran-chen
Copy link

Hi everyone. Thank you very much for the great work on zod!

I am getting an error with the following code:

const team = z
    .object({
        members: z.array(z.object({
            name: z.string(),
        })),
    })
    .catchall(z.array(z.string()));
type Team = z.infer<typeof team>;

const t1: Team = {
    members: [
        { name: 'Alice' },
    ],
    aliases: ['a', 'b'],
};

The error message is:

TS2322: Type
  {
    members: {
      name: string;
    }[];
    aliases: string[];
  }
is not assignable to type
objectOutputType<{
  members: ZodArray<ZodObject<{
      name: ZodString;
    }, 'strip', ZodTypeAny, {
      name: string;
    }, {
      name: string;
    }>, 'many'>;
  },
  ZodArray<ZodString, 'many'>,
  'strip'
>

Type
  {
    members: {
      name: string;
    }[];
    aliases: string[];
  }
is not assignable to type
{ [k: string]: string[]; }

Property members is incompatible with index signature.
Type { name: string; }[] is not assignable to type string[]
Type { name: string; } is not assignable to type string

It seems to be a bug to me - or is catchall() simply not designed to be used this way?

(I'd love to receive suggestions for a workaround.)

@JacobWeisenburger JacobWeisenburger added the bug-confirmed Bug report that is confirmed label Jan 14, 2024
@JacobWeisenburger
Copy link
Contributor

JacobWeisenburger commented Jan 14, 2024

I have confirmed this bug and here is a more simplified example based on the example in the docs.

https://github.com/colinhacks/zod#catchall

const personSchema = z.object( { name: z.string() } ).catchall( z.number() )
type Person = z.infer<typeof personSchema>
// type Person = {
//     name: string
// } & {
//     [ k: string ]: number
// }

const bobDylan: Person = {
//    ^^^^^^^^
//    Property 'name' is incompatible with index signature.
//    Type 'string' is not assignable to type 'number'.
    name: 'bob dylan',
    validExtraKey: 61,
}

@tommy-mitchell
Copy link

I believe this is due to microsoft/TypeScript#17867, not a fault with zod.

@colinhacks
Copy link
Owner

Unfortunately .catchall() is a bit of a footgun in this way. Zod treats it like a "fallback" for unrecognized keys but TypeScript requires all explicitly defined keys to conform.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug-confirmed Bug report that is confirmed
Projects
None yet
Development

No branches or pull requests

4 participants