@@ -375,7 +375,7 @@ see how the ``unevaluatedProperties`` keyword solves this problem
375375without needing to redeclare properties.
376376
377377.. index ::
378- single: object; properties
378+ single: object; properties; extending
379379 single: unevaluatedProperties
380380
381381.. _unevaluatedproperties :
@@ -385,7 +385,104 @@ Unevaluated Properties
385385
386386|draft2019-09 |
387387
388- Documentation Coming Soon
388+ In the previous section we saw the challenges with using
389+ ``additionalProperties `` when "extending" a schema using
390+ `combining `. The ``unevaluatedProperties `` keyword is similar to
391+ ``additionalProperties `` except that it can recognize properties
392+ declared in subschemas. So, the example from the previous section can
393+ be rewritten without the need to redeclare properties.
394+
395+ .. schema_example ::
396+
397+ {
398+ "allOf": [
399+ {
400+ "type": "object",
401+ "properties": {
402+ "street_address": { "type": "string" },
403+ "city": { "type": "string" },
404+ "state": { "type": "string" }
405+ },
406+ "required": ["street_address", "city", "state"]
407+ }
408+ ],
409+
410+ "properties": {
411+ "type": { "enum": ["residential", "business"] }
412+ },
413+ "required": ["type"],
414+ "unevaluatedProperties": false
415+ }
416+ --
417+ {
418+ "street_address": "1600 Pennsylvania Avenue NW",
419+ "city": "Washington",
420+ "state": "DC",
421+ "type": "business"
422+ }
423+ --X
424+ {
425+ "street_address": "1600 Pennsylvania Avenue NW",
426+ "city": "Washington",
427+ "state": "DC",
428+ "type": "business",
429+ "something that doesn't belong": "hi!"
430+ }
431+
432+ ``unevaluatedProperties `` works by collecting any properties that are
433+ successfully validated when processing the schemas and using those as
434+ the allowed list of properties. This allows you to do more complex
435+ things like conditionally adding properties. The following example
436+ allows the "department" property only if the "type" of address is
437+ "business".
438+
439+ .. schema_example ::
440+
441+ {
442+ "type": "object",
443+ "properties": {
444+ "street_address": { "type": "string" },
445+ "city": { "type": "string" },
446+ "state": { "type": "string" },
447+ "type": { "enum": ["residential", "business"] }
448+ },
449+ "required": ["street_address", "city", "state", "type"],
450+
451+ "if": {
452+ "type": "object",
453+ "properties": {
454+ "type": { "const": "business" }
455+ },
456+ "required": ["type"]
457+ },
458+ "then": {
459+ "properties": {
460+ "department": { "type": "string" }
461+ }
462+ },
463+
464+ "unevaluatedProperties": false
465+ }
466+ --
467+ {
468+ "street_address": "1600 Pennsylvania Avenue NW",
469+ "city": "Washington",
470+ "state": "DC",
471+ "type": "business",
472+ "department": "HR"
473+ }
474+ --X
475+ {
476+ "street_address": "1600 Pennsylvania Avenue NW",
477+ "city": "Washington",
478+ "state": "DC",
479+ "type": "residential",
480+ "department": "HR"
481+ }
482+
483+ In this schema, the properties declared in the ``then `` schema only
484+ count as "evaluated" properties if the "type" of the address is
485+ "business".
389486
390487.. index ::
391488 single: object; required properties
0 commit comments