nullish vs optional vs nullable in Zod
.optional()
- Type:
T | undefined - Accepts:
undefined, missing key in objects, any value passing the base schemaT - Rejects:
null(unless separately allowed) - Shorthand for "allow the value to be absent"
.nullable()
- Type:
T | null - Accepts: explicit
null, any value passingT - Rejects:
undefined, missing key - Purpose: value must be supplied but may be
null
.nullish()
- Type:
T | null | undefined - Accepts:
null,undefined, missing key, any value passingT - Internally the same as
.nullable().optional()
Interaction summary
- Missing key โ allowed only by
.optional()or.nullish() - Explicit
nullโ allowed only by.nullable()or.nullish() - Both
nulland missing/undefinedโ.nullish()
Default values
.default(val)insertsvalwhen the value isundefined; it does not act onnull, so combine with.nullable()or.nullish()according to needs
Object helpers
z.object({...}).partial()marks every key as.optional()(still disallowsnull)z.object({...}).passthrough()or.strict()do not change nullish handling; only the property schema modifiers above do