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

Optional support for tuples #149

Closed
sylvanaar opened this issue Sep 14, 2020 · 12 comments
Closed

Optional support for tuples #149

sylvanaar opened this issue Sep 14, 2020 · 12 comments
Labels
wontfix This will not be worked on

Comments

@sylvanaar
Copy link
Contributor

sylvanaar commented Sep 14, 2020

I have tried everything I can think of - however something is preventing me from writing a function type for variable number of parameters.

I can very easily write a tuple in typescript that support a variable number of elements

    type OneOrTwo = readonly [number, Record<string, string>?] 

    const one: OneOrTwo = [1] as const;
    const likeOne: OneOrTwo = [1, undefined] as const
    const two: OneOrTwo = [1, {}] as const;

However I cannot figure out how to do the same with zod.

const contract = {
    parms1: z.tuple([z.number()]),
    parms2: z.tuple([z.number(), z.record(z.any()).optional()]),
    ret: z.string(),
};

const p2 = z.tuple([z.number(), z.record(z.any()).optional()]) 
const u = z.union(contract.parms1, contract.parms2); // type error

p2.parse([1] as const) // too_small
u.parse([1] as const) //  invalid_union

It appears that it is not supported - what is involved in supporting it?

Note that since my use case is function schemas - i need to support:

[1]
[1, {}]
[1, undefined]
@colinhacks
Copy link
Owner

Huh never actually considered this use case. This is on the roadmap.

For now I recommend creating a union of tuple schemas, instead of a single tuple of optional schemas.

@sylvanaar
Copy link
Contributor Author

sylvanaar commented Sep 14, 2020

Huh never actually considered this use case. This is on the roadmap.

For now I recommend creating a union of tuple schemas, instead of a single tuple of optional schemas.

I toyed around with the implementation - and surprisingly it just seems to work more naturally with a single tuple with 2 input parameters, the required tuple, and the optional tuple where you supply the elements in non-optional form.

Then changes to the implementation.

Transform the second tuple into optionals (partial)
Then merge the 2 tuples together
Add something to know how many elements are required

In parse - modify the lower bound check of count to ensure at least count of required

Ends up looking like :

 const p2or3 = z.tuple([z.number(), z.null()] as const, [z.string()] as const)

p2or3.parse([1, null])
p2or3.parse([1, null, "test"])
p2or3.parse([1, null, undefined])

The typescript types for it will probably need Typescript 4

@sylvanaar
Copy link
Contributor Author

This will need #152 in order for the api (+ implementation) to be as nature as possible

@colinhacks
Copy link
Owner

Unfortunately I don't think this is worth bumping the minimum version to v4. There may be a way to provide TS4-specific functionality using project references...I'll look into it. If I can figure that out I'll provide an improved version of the ZodTuple that supports this.

@colinhacks colinhacks changed the title Optional Support For Tuples (and Functions) Optional support for tuples Sep 17, 2020
@stale
Copy link

stale bot commented Mar 2, 2022

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 stale bot added the wontfix This will not be worked on label Mar 2, 2022
@stale stale bot closed this as completed Mar 9, 2022
@DrParanoia
Copy link

Hey guys, is this still a work in progress? Would be nice ti have optionals support in tuples 😞

@npup
Copy link

npup commented Aug 30, 2023

My usecase is defining a list of data for image in md/x frontmatter. I would like to define tuples with the img src and an optional img alt (or title) string:

.md/x

---
images: [ [ "foo.jpg", "Picture of foo" ], [ "bar.jpg" ] ]
---

.js:

z.tuple([ z.string(), z.string.default("An image") ]);

I would find optional elements in tuples very useful!

@DrParanoia
Copy link

Well, my use case is I am defining function argument schemas for Socket.IO event handlers (basically a schema for ...args) using Zod. And not being able to provide optionals in tuples simply means that I am not able to have optional arguments in my event handlers 😢

@craftycodie
Copy link

(basically a schema for ...args)

Same use case, same problem 🥱

@phaux
Copy link

phaux commented Mar 11, 2024

@colinhacks You said it's on the roadmap but the issue is marked as wontfix by the bot.

@HananoshikaYomaru
Copy link

Oh no, this is missed out

@hoangqwe159
Copy link

@colinhacks can team support this issue, please?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

8 participants