colinhacks / zod

TypeScript-first schema validation with static type inference

Home Page:https://zod.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Calling `isOptional()` on a `coerce.bigint` throws an error

marcus13371337 opened this issue · comments

Try the following code:

const bigintSchema = z.coerce.bigint();
const isOptional = bigintSchema.isOptional();

That code should be able to run IMO, but now it throws an error, TypeError: Cannot convert undefined to a BigInt

Kind of related to the following:
#1897
#1856

I can't really see the benefit of why Zod shouldn't catch these errors and handle them in the same way as you use to with most of the other errors that can occur. What are the drawbacks of having Zod a bit smarter and having this as the default implementation of coerce.bigint?

        try {
            return BigInt( value )
        } catch ( error ) {
            ctx.addIssue( {
                code: 'invalid_type',
                expected: 'unknown',
                received: value,
                message: `Can't be parsed to BigInt`,
            } )
        }

I added an easier way to work with coerce to my utilz library. Perhaps this will help you.

https://github.com/JacobWeisenburger/zod_utilz#coerce

import { zu } from 'zod_utilz'
const bigintSchema = zu.coerce( z.bigint() )
console.log( zu.SPR( bigintSchema.safeParse( undefined ) ).error?.issues )
// [
//     {
//       code: 'invalid_type',
//       expected: 'bigint',
//       received: 'undefined',
//       path: [],
//       message: 'Required'
//     }
// ]

const isOptional = bigintSchema.isOptional() // no ts error
console.log( isOptional ) // false, as expected

@marcus13371337
Was my answer satisfactory? or would you like to leave this issue open as an enhancement request?

Yes, I was able to get around the problem by creating a custom bigint-schema. But I don't see why zod, shouldn't be able to reply of a schema is optional without crashing (which happens to be a coerce bigint), to me that's clearly a bug

same about isNullable

const f = z.coerce.bigint();
f.isNullable();

despite the fact that .isNullable() calls .safeParse().

I think the confusion comes from the expectation that coerce is expected to be fail safe.
However, it's not.
In general, I don't like this feature. It brings more issues than benefits.
CC @colinhacks