Skip to main content

nullish vs optional vs nullable in Zod

.optional()โ€‹

  • Type: T | undefined
  • Accepts: undefined, missing key in objects, any value passing the base schema T
  • Rejects: null (unless separately allowed)
  • Shorthand for "allow the value to be absent"

.nullable()โ€‹

  • Type: T | null
  • Accepts: explicit null, any value passing T
  • 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 passing T
  • 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 null and missing/undefined โ†’ .nullish()

Default valuesโ€‹

  • .default(val) inserts val when the value is undefined; it does not act on null, so combine with .nullable() or .nullish() according to needs

Object helpersโ€‹

  • z.object({...}).partial() marks every key as .optional() (still disallows null)
  • z.object({...}).passthrough() or .strict() do not change nullish handling; only the property schema modifiers above do

Links to This Note