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
pick
, omit
, require
& partial
should use arrays instead of objects
#1563
Comments
Check out #1564, it's fixable. |
Hi Igal, |
I agree with @janpaepke |
updated title and description, to include Again: I am willing to add a PR for this, but want to understand the reason for using an object in the first place. |
pick
, omit
, require
& partial
should use arrays instead of objects
@colinhacks May I ask for your insight? |
@janpaepke Prisma uses the same object notation for selecting fields. Why not have both? |
Too much of a footgun. Many many people will inevitably try this: const keys = ['a', 'b'];
const schema = z.object({
a: z.string(),
b: z.string(),
c: z.string()
}).pick(keys); // bad Which is bad because Zod can't properly type the resulting schema, since the type signature of A similar problem exists for |
@colinhacks wondering if the const modifier might make this more feasible in the future? microsoft/TypeScript#51865 |
Ah yep I misunderstood that part of the PR, my apologies. |
Hi @colinhacks, thanks for the feedback, that does make sense and I hadn't thought of that. Starting from your example: This wouldn't fail zod parsing, it would fail one step before, provided the function expects an array of the keys of T, as I wrote in my example in the original issue. Then it would fail with something like
This would point the user to the root of the issue (the type ambiguity of the provided array) and he can solve it in one of two ways: Use this to test: type O = {
a: number,
b: string,
c: boolean
}
const x = ['a', 'b'] as const
const pickTest = <T extends keyof O>(x: readonly T[]) => void x
pickTest(x); Do you still think it is an inevitable footgun, or was I able to get you to at least consider to support both syntaxes? |
@colinhacks I don't want to bother you with this, just make sure I understand your reasoning... Could you comment? |
I noticed that the input keys to schema.omit(...) are not type checked (unless user error or my behalf). The following does not warn for me that "item" is spelt incorrectly. schema.omit( { iteem: true }); // does not warn. So I created the following omitKeys() function that creates the omit params { key => true } from a type-checked list: function omitKeys(...keys: Array): { [key: string]: true } { Combined with an inferred interface, this allows passing type-checked input args as so.. export type ISchema = z.infer; Ideally you could do something like the following and the interface inference just happens behind the scenes. const reduced = schema.omit("key1", "key2"); But that might be hard so maybe you could add this method for convenience instead? |
I've discovered my "solution" breaks the inferred interface of the resulting schema which just shows {} when using the interface. Also if I only put one key in, it type checks it, but if I have multiple and one is fine, it does not. What could be happening here? const reduced = schema.omit({ const reduced = schema.omit({ const reduced = schema.omit({ I'm using webstorm |
I see there is a ticket for this already.. #2607 |
I was wondering what the rationale behind
pick
,omit
,require
andpartial
expecting objects is?Each value is optional and can only be true, so using
feels more sensible than
There is another reason than convenience:
Currently you can (accidentally) add properties, which do not exist on the original object.
With an array you could ensure type safety.
The signature would look like this
If you agree I could offer to implement this.
Either in a backwards compatible way (also accepting objects, using overloads) or as a breaking change.
The text was updated successfully, but these errors were encountered: