Tag: additional properties

  • What happens when a TypeBox schema contains additional properties?

    What happens when a TypeBox schema contains additional properties?

    By default, nothing dramatic: the data still passes. TypeBox additional properties are the fields that arrive in an object even though the schema never mentioned them, and unless you deliberately restrict them, validation accepts the object and the extra fields simply ride along untouched. They are not checked, not converted and not removed.

    Only when a schema is configured to forbid additional properties does their presence turn into a validation failure. That default surprises many developers the first time they meet it, because a schema feels like it should be a complete description of what an object may contain. In JSON Schema, however, an object schema describes the fields it cares about and stays silent about the rest, and TypeBox follows that convention.

    Whether silence is the right choice for your project is a design decision. This article explains what counts as an additional property, what happens in each configuration, and how to choose strictness deliberately.

    What Counts as an Additional Property in an Object Schema

    An additional property is any key in the data that the object schema does not declare. If a schema describes a user as having a name and an email, then an incoming object carrying a nickname, a legacy identifier or a debugging flag has three declared-or-undeclared parts: the two known fields, and everything else, which falls into the additional category.

    The category is about names, not values. An undeclared field counts as additional no matter what it holds, whether that is a harmless string or an entire nested object.

    Keeping Two Failure Kinds Separate

    Conversely, a declared field with a bad value is not an additional property problem at all; it is an ordinary validation failure on a known field. Keeping those two failure kinds separate makes error reports much easier to reason about.

    Why Extra Fields Appear in Real Systems

    Additional properties appear for mundane reasons. Producers add fields before consumers update their schemas. Older clients keep sending retired fields long after a redesign.

    Intermediaries attach metadata of their own. None of this implies malice or even carelessness; it is the normal friction of systems that evolve at different speeds, and it is why TypeBox, like JSON Schema generally, treats tolerance as the sensible starting point.

    Additional Is Not the Same as Missing

    It is also worth separating additional properties from missing ones. A schema can be relaxed about extras while remaining firm about required fields, and the two settings pull in opposite directions: one governs what may arrive uninvited, the other governs what must always show up.

    The Default Behaviour When Extra Fields Appear in Data

    Under the default configuration, validation looks the other way. The validator checks every declared field against its rules and ignores the rest of the object entirely. An object with the right name and email plus four undeclared fields validates exactly as cleanly as the same object with nothing extra.

    The extra fields are also left physically untouched. They remain in the object after validation, available to any later code that happens to look for them, and they will be serialised along with everything else if the object is sent onward. This pass-through quality is why tolerant schemas are popular at system boundaries that aggregate data from several sources: nothing is silently destroyed on the way through.

    What Tolerance Means for Stored Data

    There is a subtle consequence for teams that store validated data. Whatever extra fields arrived are what gets stored, including fields nobody on the team recognises.

    Over time, stored objects accumulate historical extras like sediment. That is rarely an emergency, but it explains the mysterious legacy keys that surface whenever someone finally inspects the database with fresh eyes.

    Why the Default Optimises for Interoperability

    The default, in short, optimises for interoperability. Producers and consumers can evolve independently, minor version differences stop being breaking changes, and the schema enforces the contract it actually cares about rather than policing everything that travels with the data.

    How Validation Results Change When Additional Properties Are Restricted

    Restricting additional properties flips the validator’s posture from tolerance to gatekeeping. With the restriction switched on for an object schema, the presence of any undeclared key fails validation, even when every declared field is perfectly valid. The error identifies the offending property, so the sender can see exactly which field the schema refused to accept.

    This is a stronger contract, and it changes the failure profile of a system. Requests that previously sailed through now fail because a client sent a field the schema does not know. During development that strictness is valuable: typos in field names, which tolerant validation would let slip through as silent extras while the intended field stayed missing, are caught immediately and noisily.

    Selective Strictness and the Removal Alternative

    Strictness can also be applied selectively. A schema language that treats each object independently lets you forbid extras on sensitive objects while leaving aggregating or forwarding objects tolerant. Nested objects make their own choices too, so a strict outer record can contain a deliberately open inner one, such as a metadata bag whose whole purpose is to carry arbitrary extras.

    A related middle path is removal rather than rejection. Some teams prefer tooling that strips undeclared fields during or after validation, keeping the data that matters and discarding the rest. That approach suits stored data and forwarded messages, though it should be a deliberate pipeline step rather than a surprise, because silently discarding fields that another system expected can move the bug rather than fix it.

    How Extra Fields Affect the TypeScript Side of the Schema

    On the static side, the generated type describes the declared fields and says nothing about extras, which creates an asymmetry worth understanding. At runtime an object may carry additional properties; in the type system, those properties are invisible. Code reading validated data through its type sees exactly the declared shape and nothing more.

    TypeScript’s own behaviour adds a wrinkle. The language performs excess property checks on fresh object literals, so hand-written data assigned directly in code can be flagged for extra fields even while identical data arriving from outside passes validation without comment. Developers occasionally find this backwards, strict where they write data and relaxed where they receive it, but each behaviour guards a different moment: literals are checked at authoring time, external data at the boundary.

    The Practical Consequence for Trusting Your Data

    The practical consequence is about trust. Code that needs a field should not assume it can fish undeclared extras out of validated data in a type-safe way, because the type does not know they exist.

    If a field matters, declare it in the schema, possibly as optional. That is also the correct response when a supposedly extra field turns out to be load-bearing in production: promote it into the contract, where both the validator and the types can see it. Questions about declared-but-absent fields belong to the neighbouring topic of what happens when an optional property is missing, which pairs naturally with the strictness decision.

    Deciding Strictness for APIs That Receive Outside Data

    For public APIs and webhooks, tolerance is usually the safer default. Senders include partner systems, older mobile apps and third-party tools you do not control. Rejecting their requests over an extra field they consider harmless creates integration failures that are hard to debug from the other side, and the sender often cannot change quickly even when they want to.

    Strictness earns its keep in narrower settings. Internal messages between services owned by one team benefit from loud failures, because both sides can be fixed in the same afternoon. Security-sensitive payloads are another candidate: when an object drives permissions, pricing or identity, accepting undeclared fields creates room for confusion about which fields actually influenced a decision, and a strict schema removes that ambiguity.

    A Layered Policy Many Teams Adopt

    A workable policy many teams adopt is layered. The public boundary stays tolerant so integrations do not shatter, while the objects that drive internal decisions are strict. Whichever you choose, document it per schema rather than by habit, because the next developer will otherwise assume the opposite of what you intended.

    When to Revisit the Choice

    Revisit the choice when the data changes owners. A schema written for an internal tool that later becomes a partner-facing contract should usually loosen; a tolerant prototype that hardens into a payment flow should usually tighten.

    Strictness is not a personality trait of the codebase. It is a per-boundary decision about who sends the data and what a surprise field could cost.

    Frequently Asked Questions

    Does TypeBox reject extra fields by default?

    No. Following JSON Schema convention, extra fields are allowed by default and pass through validation untouched. Rejection happens only when the object schema is configured to restrict additional properties.

    Are additional properties removed during validation?

    Not by the validator itself. Extra fields stay in the object after a successful check. Removing them is a separate, deliberate step some teams add to their pipeline.

    Can I forbid extra fields on one object but allow them on another?

    Yes. The setting belongs to each object schema individually, including nested objects, so strict and tolerant shapes can be mixed within a single larger schema.

    Do extra fields appear in the generated TypeScript type?

    No. The generated type contains only the declared fields. Extras may exist at runtime, but code cannot access them in a type-safe way unless they are declared in the schema.

    Conclusion

    When a TypeBox schema contains additional properties in the data it receives, the default outcome is calm acceptance: declared fields are checked, extras are ignored and left in place. Restricting them turns the same situation into a clear validation failure, which protects sensitive contracts and catches naming mistakes early.

    The generated types only ever describe declared fields, so anything that matters should be written into the schema. Choose tolerance at open boundaries and strictness where surprises are expensive, and the behaviour stops being a surprise itself.

  • Is it possible to define strict object properties using TypeBox?

    Is it possible to define strict object properties using TypeBox?

    Yes, TypeBox allows developers to define strict object properties by controlling whether additional properties are accepted during validation. This makes it possible to restrict an object to predefined fields and reject unexpected properties that do not belong to its schema.

    TypeBox strict objects are useful when applications need predictable data structures, reliable API validation, and better control over incoming information. By combining defined properties, required fields, and additional property restrictions, developers can create object schemas that maintain consistent data formats across their applications.

    How TypeBox Defines Strict Objects

    TypeBox defines object structures through Type.Object, allowing developers to specify which properties an object can contain. Each property can have its own data type and validation requirements, giving developers control over the expected structure of incoming data.

    To make an object strict, developers can configure its additional property behavior. This allows the schema to distinguish between predefined properties and unexpected fields, helping applications maintain consistent object structures during runtime validation.

    Preventing Additional Properties in TypeBox

    TypeBox supports restricting additional properties through the additionalProperties setting. When this setting is disabled, an object can contain only the properties explicitly defined in its schema, and unexpected fields fail validation.

    This is particularly useful for API requests and configuration objects where accepting unknown properties could create inconsistent data. Strict validation ensures that incoming objects follow the expected structure instead of silently accepting fields that the application does not recognize.

    Difference Between Required and Optional Properties

    Required and optional properties determine whether a field must exist inside an object. TypeBox treats these requirements separately from additional property restrictions, allowing developers to control both field presence and the overall object structure.

    A required property must be included for the object to pass validation, while an optional property can be omitted without making the object invalid. However, optional properties must still follow their defined data types when provided, and strict object settings can prevent unrelated fields from being accepted.

    How TypeBox Validates Object Properties

    TypeBox validates object properties by checking incoming values against the rules defined in the schema. These rules can include data types, required fields, string constraints, numeric limits, and other supported validation conditions.

    During runtime validation, the object must satisfy the applicable property requirements and additional property restrictions. This helps developers ensure that incoming data follows the expected structure before it is used by application logic or passed to other services.

    Handling Unexpected Properties During Validation

    Unexpected properties are fields that appear in an object but are not included in its schema definition. In a strict TypeBox object, these fields are rejected when additional properties are disabled, preventing unrecognized information from passing validation.

    This behavior is important when working with external API requests, user-submitted data, and application settings. Rejecting unexpected properties makes data structures more predictable and helps developers identify incorrect or unsupported fields before they affect application behavior.

    Common Use Cases for Strict Object Schemas

    Strict object schemas are useful whenever an application requires a clearly defined data format. They help developers maintain consistent structures across different application components and reduce the possibility of unexpected fields entering important workflows.

    Common use cases include:

    • API request validation: Accept only supported request properties.
    • User registration: Restrict submitted fields to approved account information.
    • Configuration objects: Prevent unknown settings from being accepted.
    • Database operations: Validate object structures before processing data.
    • Authentication systems: Control which properties are accepted in authentication requests.
    • Data exchange: Maintain predictable object formats between services.

    Best Practices for Defining Strict Objects

    When creating strict TypeBox schemas, developers should define only the properties required by their application and apply appropriate validation rules to each field. Required and optional properties should be selected carefully so that the schema reflects the actual data structure rather than rejecting legitimate input.

    It is also important to consider how strict validation affects nested objects and composed schemas. Each object level may need its own additional property restrictions, depending on the intended structure. Reviewing these rules helps prevent unexpected fields while keeping schema validation consistent and maintainable.

    Conclusion

    TypeBox makes it possible to define strict object properties by controlling additional property acceptance within object schemas. Developers can specify allowed fields, enforce required properties, and reject unexpected data during runtime validation. Using TypeBox strict objects helps maintain predictable data structures, improve API request validation, and create more reliable TypeScript applications.