Tag: optional properties

  • What happens when an optional TypeBox property is missing?

    What happens when an optional TypeBox property is missing?

    Nothing goes wrong. When an optional property is missing, validation simply passes, because TypeBox optional properties are allowed to be absent. The validator skips the missing field entirely, the object is accepted as it stands, and only a missing required property would produce an error.

    That simple answer hides a few details worth understanding, because optional is easily confused with neighbouring ideas. An absent optional field is not filled in with a default value, it does not turn into an empty value, and it is not the same thing as permitting a null. The TypeScript type generated from the schema also records that the property may not be there, so code reading the object is pushed to handle both possibilities.

    This article covers how a property comes to be marked optional in a schema built with TypeBox. It explains what validation does when the property is absent, how the absence appears in your types, how missing differs from empty or explicitly unset values, and how to mix optional and required properties sensibly.

    How a Property Is Marked Optional in a Schema

    Every declared property in an object schema starts out required. An object that lacks any one of them fails validation, because the schema is read as a contract about exactly what an object must contain.

    The Optional modifier changes the deal for one property at a time. Wrapping a property’s schema with it declares that the property may be omitted; in effect, the property leaves the schema’s required list while keeping every other rule attached to it. Its neighbours are untouched, so optionality is precise rather than contagious.

    Marking Every Property Optional at Once

    There is also a whole-object variation. A partial version of a schema marks every property optional at once, which is exactly what update-style payloads usually want. Per-property marking suits objects you are designing, while the partial transformation suits objects you are reusing for a different job.

    One distinction is worth fixing early. Optionality governs presence only: it says whether the property must appear. What values are acceptable when it does appear remains entirely the business of the property’s own schema.

    Optional Markers Double as Documentation

    Optionality recorded in the schema doubles as documentation. Because the marker is machine-readable, generated API documentation and client tools can show which fields may be skipped. Consumers of the API learn the contract from the schema itself instead of from guesswork or support tickets.

    What Validation Does When the Property Is Absent

    Validating an object involves two kinds of checks. The validator confirms that every required property is present and valid, and it checks any optional property that happens to be present against its rules. An absent optional property has nothing to check, so it is passed over without comment.

    Presence changes everything, though. If the property does appear, it is validated exactly as strictly as a required one. A wrong type or a broken constraint fails the whole check, because optional is permission to be absent, not permission to be anything at all.

    Absent Optional Versus Missing Required

    The contrast with a missing required property is stark. That absence fails validation immediately, with an error identifying the field that should have been there. One kind of absence is part of the contract; the other is a breach of it.

    Finally, validation inspects data but never modifies it. The object that passes is the object that arrived: no key is added carrying an empty or undefined value. Downstream code sees precisely what the sender sent, nothing more.

    The Same Rule Inside Nested Objects and Arrays

    The same behaviour repeats at every level of the data. An optional property inside a nested object is skipped when absent, exactly as at the top level. Objects inside arrays follow the identical rule, item by item, so there are no special cases to memorise.

    How an Absent Optional Property Shows Up in the TypeScript Type

    The static type generated from the schema marks the property as optional too. Reading it can therefore produce either the expected value or nothing at all, and TypeScript insists that consuming code cope with both outcomes before using the value.

    In practice, this means a presence check or a fallback wherever the field is used. Teams occasionally find that friction annoying, but it is the system working as intended. A field the API is allowed to omit can never be treated as guaranteed by accident.

    One Schema Keeps Types and Validation in Step

    The deeper benefit is that the two views cannot drift apart. One schema produces both the runtime check and the compile-time type, so changing a property from required to optional updates validation and types together. There is no separate type definition waiting to be forgotten.

    That coupling also guides schema evolution. When a property flips from required to optional, type errors appear at every place the code assumed its presence, marking the spots that need a second look. The compiler produces the migration checklist for free.

    The Difference Between Missing, Empty, and Explicitly Unset Values

    Three states are confused constantly, and they behave very differently. A property can be missing entirely, present with an empty value such as an empty string or a zero, or present while carrying an explicitly unset marker like undefined or null.

    Empty is a real value and is judged as one. An optional text field that arrives empty still faces its constraints, so a minimum-length rule will reject the empty string even though omitting the field altogether would have passed. Clients that send blank fields instead of leaving them out meet failures they did not expect.

    Undefined and Null Behave Differently Again

    Undefined occupies a grey area. JSON has no undefined value, so serialised payloads simply drop such keys, and present-but-undefined usually becomes plain missing by the time an API receives it. Data held in memory can carry undefined, and there it is generally treated like absence.

    Null is different again, because it is a genuine JSON value that gets checked like any other. It will fail a string schema unless the schema deliberately allows null among the permitted kinds of value. If your API uses null as a “clear this field” signal, that permission has to be granted explicitly; optionality does not grant it.

    Why Forms Make the Empty Case So Common

    Everyday clients make the empty case common. Web forms, for example, submit an empty string for every field the user left untouched, so APIs routinely receive present-but-empty values where the sender meant nothing to say. Deciding whether to trim such values into absence, or reject them, is a deliberate design choice worth making once and documenting.

    Mixing Optional and Required Properties in One Object

    Real objects almost always mix the two. An account cannot function without an email address and a password, so those are required. A display name, an avatar, and a preferred timezone are refinements, so they are natural candidates for optional.

    The working rule is to ask what the feature breaks without. If the answer is “everything”, the property is required; if the answer is “nothing important”, it is optional. Schemas that follow the rule state the real minimum a feature needs, and validation becomes meaningful again.

    The Trap of Marking Everything Optional

    The opposite habit is the trap. Marking everything optional makes validation guarantee almost nothing, and the cost reappears as absence checks scattered through every corner of the codebase. Generous optionality feels flexible and quietly taxes everything downstream.

    Creation and update payloads often want different mixtures. A creation schema is strict, while an update schema frequently wants the partial, all-optional variant with unchanged per-field rules. Deriving both from one source schema keeps them consistent instead of maintaining two definitions by hand.

    Defaults, Extra Fields, and Schema Evolution

    Optionality also interacts with how undeclared fields are treated, which is a separate decision covered in how extra properties are handled by a schema. Settling both questions together produces an object contract with no surprises. And if a missing optional field should behave as though it had a standard value, apply that default in application code after validation; the schema alone will not supply it.

    Evolution cuts in one safe direction. Relaxing a required property to optional never breaks existing senders, because everything they used to send still passes. Tightening an optional property to required does the opposite, silently invalidating clients that omit it, so it should be treated as a breaking change.

    Frequently Asked Questions

    Does a missing optional property ever cause a validation error?

    No. Absence is exactly what optional permits, so the field is skipped. Errors arise from missing required properties, or from properties that are present but break their rules.

    Is an optional property the same as one that allows null?

    No. Optional concerns whether the property appears at all. Null is a present value, and it must be allowed in its own right if you want it accepted.

    Will validation fill in a default when the field is missing?

    No. Validation only checks the data it receives and leaves that data unchanged. Applying defaults afterwards is a small, deliberate step in your own code.

    Can I make all properties optional for update requests?

    Yes. A partial variant of the schema does exactly that, keeping every field’s rules intact for whichever fields a client chooses to send.

    Conclusion

    A missing optional property is the quietest outcome in validation: the check passes, nothing is added or invented, and the type system reminds every reader that the field might not be there. Keep required for what features truly need, reserve optional for genuine extras, and stay precise about the difference between missing, empty, and null. With those distinctions clear, optional properties become a modelling tool instead of a source of surprises.