I got one whole 👍 on that issue and I think it's a good idea so opening a PR.
hi - I find z.date({ coerce: true }) very useful when using with trpc or another tool that uses JSON to cross an i/o boundary. Because, it forces the client to use a Date value - which is then serialized via its toJSON method into an ISO string and correctly converted back to a Date on the other side. So you get nice Date types on either side of the boundary.
But a not-ideal effect of using that trick is that it will also accept values like null and 0 which both parse to 1970-01-01T00:00:00.000Z, so it's a bit dangerous.
This PR makes that type change, and implements it by using new Date(...) and checking that the original input exactly matches the resultant .toISOString() value.
It also adds some tests to 1) highlight the danger of coerce: true and 2) make sure everything works sensibly with coerce: 'iso'.
Closes #3643
I got one whole 👍 on that issue and I think it's a good idea so opening a PR.
hi - I find
z.date({ coerce: true })
very useful when using with trpc or another tool that uses JSON to cross an i/o boundary. Because, it forces the client to use aDate
value - which is then serialized via itstoJSON
method into an ISO string and correctly converted back to aDate
on the other side. So you get niceDate
types on either side of the boundary.But a not-ideal effect of using that trick is that it will also accept values like
null
and0
which both parse to1970-01-01T00:00:00.000Z
, so it's a bit dangerous.The change here is to change
coerce: boolean
tocoerce: boolean | 'iso'
, then update this block: https://github.com/colinhacks/zod/blob/9257ab78eec366c04331a3c2d59deb344a02d9f6/src/types.ts#L1798-L1800This PR makes that type change, and implements it by using new Date(...) and checking that the original input exactly matches the resultant .toISOString() value.
It also adds some tests to 1) highlight the danger of coerce: true and 2) make sure everything works sensibly with coerce: 'iso'.