zod icon indicating copy to clipboard operation
zod copied to clipboard

Doubts about type inference when using picks

Open fxioi opened this issue 2 years ago • 3 comments

Hello everyone, when calling the pick method of a zodObject in a function by passing in a reference, how to set the type of T to ensure the correct type of return value?

function zodPickDemo<T extends ZodObject<ZodRawShape>>(src: T) {
  return src.pick({ id: true });
}

const dto = z.object({ id: z.string(), name: z.string() });
const picked = zodPickDemo(dto);
// In this case the type of picked is not the expected type

In the above code, the type expected to be obtained is a zodObject object type containing only the id, but what is obtained is a type such that:

z.ZodObject<Pick<z.ZodRawShape, never>, "strip", z.ZodTypeAny, {}, {}>

Playground: link

fxioi avatar May 30 '22 03:05 fxioi

Found this: https://github.com/colinhacks/zod/issues/567

For the time being, this is the way to handle it.

ZodObject<
  Pick<ReturnType<T["_def"]["shape"]>, 'id'>,
  T["_def"]["unknownKeys"],
  T["_def"]["catchall"]
>

fxioi avatar May 30 '22 09:05 fxioi

I managed to get the correct functionality with this code:

import type { ZodObject, ZodTypeAny } from 'zod';
import { z } from 'zod';

function zodPickDemo<T extends ZodTypeAny>(src: ZodObject<{id: T}>): ZodObject<{id: T}> {
  return src.pick({ id: true });
}

const dto = z.object({ id: z.string(), name: z.string() });
const picked = zodPickDemo(dto);
picked.shape.id; // z.ZodString

Does this solve your problem?

AustinShelby avatar Jul 03 '22 16:07 AustinShelby

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Sep 01 '22 16:09 stale[bot]

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Oct 31 '22 17:10 stale[bot]

Thanks @AustinShelby for providing the working code, that does seem to be the correct way to address the original question.

scotttrinh avatar Nov 01 '22 14:11 scotttrinh