question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Value or undefined is not the same as an optional, and should not be a required property either

See original GitHub issue

Discussed in https://github.com/colinhacks/zod/discussions/971

<div type='discussions-op-text'>

Originally posted by emanuel-lundman February 7, 2022

type A = {
    b: string | undefined
}

is not the same as:

type A = {
    b?: string | undefined
}

The first requires undefined to be set, and can’t just be left out.

Zod though both seem to infer:

type A = {
    b: string | undefined
}

to an optional when writing the schema first and then inferring a type. And when doing the other way around, writing a schema for the type, thinks it’s required and only accepts the following:

type A = {
    b: string | undefined
}

const a = z.ZodScheme<A> = z.object({
    b: z.string()
})

even though it should be z.string().or(z.undefined()) But writing is it should be results in error: Property 'b' is optional in type '{ b?: string | undefined; }' but required in type 'A'

Am I missing something?</div>

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:4
  • Comments:7 (1 by maintainers)

github_iconTop GitHub Comments

4reactions
colinhackscommented, Mar 1, 2022

Known design limitation. Technically property optionality should be defined on z.object somehow, since it’s not an inherent property of the child schema. But I decided a long time ago that question marks should get automatically added if an “or-undefined” schema is used in an object schema. Any other default behavior would be unacceptably verbose.

const base = z.object({
  hello: z.string().optional()
});  // {hello: string | optional}

base.partial({ hello: true })
// {hello?: string | optional}

The best API solution here is to add a method to ZodObject that removes the question marks if needed:

const base = z.object({
  hello: z.string().optional()
});  // {hello?: string | optional}

base.require({ hello: true })
// {hello: string | optional}

Thoughts?

2reactions
akommcommented, Aug 31, 2022

It got even worser now btw. Now if you want a {[P in K]?: V} where undefined can not be assigned directly, you are screwed with this library, because it adds explicit | undefined everywhere, eliminating taking advantage of exactOptionalPropertyTypes, where you don’t want undefined assignment.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to Deal with Optional Things and "Undefined" in TypeScript
Working with JavaScript means working with undefined . It's a standard way to say, “This thing you asked for doesn't exist.”.
Read more >
When to use typescript optional "?" parameter vs explicit ...
Undefined means that parameter must be passed in but its value may be undefined.
Read more >
optional vs. undefined - TkDodo's blog
There is a subtle difference between optional fields and required, but potentially undefined ones.
Read more >
TypeScript optional properties not accepting undefined value
Based on the linked answer, I think you have to specify undefined as a possible type for the prop, so type?: string |...
Read more >
Validation should fail when required property (which may be ...
Folks who insist on doing this should be using "null" to distinguish between "defined as not having a value" and "undefined" (which means ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found