diff --git a/base/cplusplus/test/inputs/json/priority/bug427.json/default/quicktype.hpp b/head/cplusplus/test/inputs/json/priority/bug427.json/default/quicktype.hpp
index 0e21d06..e75bad1 100644
--- a/base/cplusplus/test/inputs/json/priority/bug427.json/default/quicktype.hpp
+++ b/head/cplusplus/test/inputs/json/priority/bug427.json/default/quicktype.hpp
@@ -1067,7 +1067,7 @@ namespace quicktype {
         std::string name;
         std::shared_ptr<ExtendedBy> overwrites;
         std::optional<std::vector<PurpleParameter>> parameters;
-        ExtendedBy type;
+        std::shared_ptr<ExtendedBy> type;
         std::optional<std::vector<GetSignature>> type_parameter;
 
         public:
@@ -1111,9 +1111,9 @@ namespace quicktype {
         std::optional<std::vector<PurpleParameter>> & get_mutable_parameters() { return parameters; }
         void set_parameters(const std::optional<std::vector<PurpleParameter>> & value) { this->parameters = value; }
 
-        const ExtendedBy & get_type() const { return type; }
-        ExtendedBy & get_mutable_type() { return type; }
-        void set_type(const ExtendedBy & value) { this->type = value; }
+        const std::shared_ptr<ExtendedBy> & get_type() const { return type; }
+        std::shared_ptr<ExtendedBy> & get_mutable_type() { return type; }
+        void set_type(const std::shared_ptr<ExtendedBy> & value) { this->type = value; }
 
         const std::optional<std::vector<GetSignature>> & get_type_parameter() const { return type_parameter; }
         std::optional<std::vector<GetSignature>> & get_mutable_type_parameter() { return type_parameter; }
@@ -1342,7 +1342,7 @@ namespace quicktype {
         SignatureKindString kind_string;
         std::string name;
         std::optional<std::vector<FluffyParameter>> parameters;
-        ExtendedBy type;
+        std::shared_ptr<ExtendedBy> type;
 
         public:
         const std::optional<IndigoComment> & get_comment() const { return comment; }
@@ -1373,9 +1373,9 @@ namespace quicktype {
         std::optional<std::vector<FluffyParameter>> & get_mutable_parameters() { return parameters; }
         void set_parameters(const std::optional<std::vector<FluffyParameter>> & value) { this->parameters = value; }
 
-        const ExtendedBy & get_type() const { return type; }
-        ExtendedBy & get_mutable_type() { return type; }
-        void set_type(const ExtendedBy & value) { this->type = value; }
+        const std::shared_ptr<ExtendedBy> & get_type() const { return type; }
+        std::shared_ptr<ExtendedBy> & get_mutable_type() { return type; }
+        void set_type(const std::shared_ptr<ExtendedBy> & value) { this->type = value; }
     };
 
     class FluffyDeclaration {
@@ -3190,7 +3190,7 @@ namespace quicktype {
         x.set_name(j.at("name").get<std::string>());
         x.set_overwrites(get_heap_optional<ExtendedBy>(j, "overwrites"));
         x.set_parameters(get_stack_optional<std::vector<PurpleParameter>>(j, "parameters"));
-        x.set_type(j.at("type").get<ExtendedBy>());
+        x.set_type(j.at("type").get<std::shared_ptr<ExtendedBy>>());
         x.set_type_parameter(get_stack_optional<std::vector<GetSignature>>(j, "typeParameter"));
     }
 
@@ -3322,7 +3322,7 @@ namespace quicktype {
         x.set_kind_string(j.at("kindString").get<SignatureKindString>());
         x.set_name(j.at("name").get<std::string>());
         x.set_parameters(get_stack_optional<std::vector<FluffyParameter>>(j, "parameters"));
-        x.set_type(j.at("type").get<ExtendedBy>());
+        x.set_type(j.at("type").get<std::shared_ptr<ExtendedBy>>());
     }
 
     inline void to_json(json & j, const TentacledSignature & x) {
diff --git a/head/schema-cjson/test/inputs/schema/required-in-any-of.schema/default/TopLevel.c b/head/schema-cjson/test/inputs/schema/required-in-any-of.schema/default/TopLevel.c
new file mode 100644
index 0000000..3054f0d
--- /dev/null
+++ b/head/schema-cjson/test/inputs/schema/required-in-any-of.schema/default/TopLevel.c
@@ -0,0 +1,137 @@
+/**
+ * TopLevel.c
+ * This file has been autogenerated using quicktype https://github.com/quicktype/quicktype - DO NOT EDIT
+ */
+
+#include "TopLevel.h"
+
+struct Anyof * cJSON_ParseAnyof(const char * s) {
+    struct Anyof * x = NULL;
+    if (NULL != s) {
+        cJSON * j = cJSON_Parse(s);
+        if (NULL != j) {
+            x = cJSON_GetAnyofValue(j);
+            cJSON_Delete(j);
+        }
+    }
+    return x;
+}
+
+struct Anyof * cJSON_GetAnyofValue(const cJSON * j) {
+    struct Anyof * x = NULL;
+    if (NULL != j) {
+        if (NULL != (x = cJSON_malloc(sizeof(struct Anyof)))) {
+            memset(x, 0, sizeof(struct Anyof));
+            if (cJSON_HasObjectItem(j, "name")) {
+                x->name = strdup(cJSON_GetStringValue(cJSON_GetObjectItemCaseSensitive(j, "name")));
+            }
+            else {
+                if (NULL != (x->name = cJSON_malloc(sizeof(char)))) {
+                    x->name[0] = '\0';
+                }
+            }
+            if (cJSON_HasObjectItem(j, "size")) {
+                x->size = strdup(cJSON_GetStringValue(cJSON_GetObjectItemCaseSensitive(j, "size")));
+            }
+        }
+    }
+    return x;
+}
+
+cJSON * cJSON_CreateAnyof(const struct Anyof * x) {
+    cJSON * j = NULL;
+    if (NULL != x) {
+        if (NULL != (j = cJSON_CreateObject())) {
+            if (NULL != x->name) {
+                cJSON_AddStringToObject(j, "name", x->name);
+            }
+            else {
+                cJSON_AddStringToObject(j, "name", "");
+            }
+            if (NULL != x->size) {
+                cJSON_AddStringToObject(j, "size", x->size);
+            }
+        }
+    }
+    return j;
+}
+
+char * cJSON_PrintAnyof(const struct Anyof * x) {
+    char * s = NULL;
+    if (NULL != x) {
+        cJSON * j = cJSON_CreateAnyof(x);
+        if (NULL != j) {
+            s = cJSON_Print(j);
+            cJSON_Delete(j);
+        }
+    }
+    return s;
+}
+
+void cJSON_DeleteAnyof(struct Anyof * x) {
+    if (NULL != x) {
+        if (NULL != x->name) {
+            cJSON_free(x->name);
+        }
+        if (NULL != x->size) {
+            cJSON_free(x->size);
+        }
+        cJSON_free(x);
+    }
+}
+
+struct TopLevel * cJSON_ParseTopLevel(const char * s) {
+    struct TopLevel * x = NULL;
+    if (NULL != s) {
+        cJSON * j = cJSON_Parse(s);
+        if (NULL != j) {
+            x = cJSON_GetTopLevelValue(j);
+            cJSON_Delete(j);
+        }
+    }
+    return x;
+}
+
+struct TopLevel * cJSON_GetTopLevelValue(const cJSON * j) {
+    struct TopLevel * x = NULL;
+    if (NULL != j) {
+        if (NULL != (x = cJSON_malloc(sizeof(struct TopLevel)))) {
+            memset(x, 0, sizeof(struct TopLevel));
+            if (cJSON_HasObjectItem(j, "anyof")) {
+                x->anyof = cJSON_GetAnyofValue(cJSON_GetObjectItemCaseSensitive(j, "anyof"));
+            }
+        }
+    }
+    return x;
+}
+
+cJSON * cJSON_CreateTopLevel(const struct TopLevel * x) {
+    cJSON * j = NULL;
+    if (NULL != x) {
+        if (NULL != (j = cJSON_CreateObject())) {
+            cJSON_AddItemToObject(j, "anyof", cJSON_CreateAnyof(x->anyof));
+        }
+    }
+    return j;
+}
+
+char * cJSON_PrintTopLevel(const struct TopLevel * x) {
+    char * s = NULL;
+    if (NULL != x) {
+        cJSON * j = cJSON_CreateTopLevel(x);
+        if (NULL != j) {
+            s = cJSON_Print(j);
+            cJSON_Delete(j);
+        }
+    }
+    return s;
+}
+
+void cJSON_DeleteTopLevel(struct TopLevel * x) {
+    if (NULL != x) {
+        if (NULL != x->anyof) {
+            cJSON_DeleteAnyof(x->anyof);
+        }
+        cJSON_free(x);
+    }
+}
diff --git a/head/schema-cjson/test/inputs/schema/required-in-any-of.schema/default/TopLevel.h b/head/schema-cjson/test/inputs/schema/required-in-any-of.schema/default/TopLevel.h
new file mode 100644
index 0000000..6036716
--- /dev/null
+++ b/head/schema-cjson/test/inputs/schema/required-in-any-of.schema/default/TopLevel.h
@@ -0,0 +1,62 @@
+/**
+ * TopLevel.h
+ * This file has been autogenerated using quicktype https://github.com/quicktype/quicktype - DO NOT EDIT
+ * This file depends of https://github.com/DaveGamble/cJSON, https://github.com/joelguittet/c-list and https://github.com/joelguittet/c-hashtable
+ * To parse json data from json string use the following: struct <type> * data = cJSON_Parse<type>(<string>);
+ * To get json data from cJSON object use the following: struct <type> * data = cJSON_Get<type>Value(<cjson>);
+ * To get cJSON object from json data use the following: cJSON * cjson = cJSON_Create<type>(<data>);
+ * To print json string from json data use the following: char * string = cJSON_Print<type>(<data>);
+ * To delete json data use the following: cJSON_Delete<type>(<data>);
+ */
+
+#ifndef __TOPLEVEL_H__
+#define __TOPLEVEL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <cJSON.h>
+#include <hashtable.h>
+#include <list.h>
+
+#ifndef cJSON_Bool
+#define cJSON_Bool (cJSON_True | cJSON_False)
+#endif
+#ifndef cJSON_Map
+#define cJSON_Map (1 << 16)
+#endif
+#ifndef cJSON_Enum
+#define cJSON_Enum (1 << 17)
+#endif
+
+struct Anyof {
+    char * name;
+    char * size;
+};
+
+struct TopLevel {
+    struct Anyof * anyof;
+};
+
+struct Anyof * cJSON_ParseAnyof(const char * s);
+struct Anyof * cJSON_GetAnyofValue(const cJSON * j);
+cJSON * cJSON_CreateAnyof(const struct Anyof * x);
+char * cJSON_PrintAnyof(const struct Anyof * x);
+void cJSON_DeleteAnyof(struct Anyof * x);
+
+struct TopLevel * cJSON_ParseTopLevel(const char * s);
+struct TopLevel * cJSON_GetTopLevelValue(const cJSON * j);
+cJSON * cJSON_CreateTopLevel(const struct TopLevel * x);
+char * cJSON_PrintTopLevel(const struct TopLevel * x);
+void cJSON_DeleteTopLevel(struct TopLevel * x);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TOPLEVEL_H__ */
diff --git a/head/schema-cplusplus/test/inputs/schema/required-in-any-of.schema/default/quicktype.hpp b/head/schema-cplusplus/test/inputs/schema/required-in-any-of.schema/default/quicktype.hpp
new file mode 100644
index 0000000..8d38134
--- /dev/null
+++ b/head/schema-cplusplus/test/inputs/schema/required-in-any-of.schema/default/quicktype.hpp
@@ -0,0 +1,151 @@
+//  To parse this JSON data, first install
+//
+//      json.hpp  https://github.com/nlohmann/json
+//
+//  Then include this file, and then do
+//
+//     TopLevel data = nlohmann::json::parse(jsonString);
+
+#pragma once
+
+#include <optional>
+#include "json.hpp"
+
+#include <optional>
+#include <stdexcept>
+#include <regex>
+
+#ifndef NLOHMANN_OPT_HELPER
+#define NLOHMANN_OPT_HELPER
+namespace nlohmann {
+    template <typename T>
+    struct adl_serializer<std::shared_ptr<T>> {
+        static void to_json(json & j, const std::shared_ptr<T> & opt) {
+            if (!opt) j = nullptr; else j = *opt;
+        }
+
+        static std::shared_ptr<T> from_json(const json & j) {
+            if (j.is_null()) return std::shared_ptr<T>(); else return std::make_shared<T>(j.get<T>());
+        }
+    };
+    template <typename T>
+    struct adl_serializer<std::optional<T>> {
+        static void to_json(json & j, const std::optional<T> & opt) {
+            if (!opt) j = nullptr; else j = *opt;
+        }
+
+        static std::optional<T> from_json(const json & j) {
+            if (j.is_null()) return std::optional<T>(); else return std::make_optional<T>(j.get<T>());
+        }
+    };
+}
+#endif
+
+namespace quicktype {
+    using nlohmann::json;
+
+    #ifndef NLOHMANN_UNTYPED_quicktype_HELPER
+    #define NLOHMANN_UNTYPED_quicktype_HELPER
+    inline json get_untyped(const json & j, const char * property) {
+        if (j.find(property) != j.end()) {
+            return j.at(property).get<json>();
+        }
+        return json();
+    }
+
+    inline json get_untyped(const json & j, std::string property) {
+        return get_untyped(j, property.data());
+    }
+    #endif
+
+    #ifndef NLOHMANN_OPTIONAL_quicktype_HELPER
+    #define NLOHMANN_OPTIONAL_quicktype_HELPER
+    template <typename T>
+    inline std::shared_ptr<T> get_heap_optional(const json & j, const char * property) {
+        auto it = j.find(property);
+        if (it != j.end() && !it->is_null()) {
+            return j.at(property).get<std::shared_ptr<T>>();
+        }
+        return std::shared_ptr<T>();
+    }
+
+    template <typename T>
+    inline std::shared_ptr<T> get_heap_optional(const json & j, std::string property) {
+        return get_heap_optional<T>(j, property.data());
+    }
+    template <typename T>
+    inline std::optional<T> get_stack_optional(const json & j, const char * property) {
+        auto it = j.find(property);
+        if (it != j.end() && !it->is_null()) {
+            return j.at(property).get<std::optional<T>>();
+        }
+        return std::optional<T>();
+    }
+
+    template <typename T>
+    inline std::optional<T> get_stack_optional(const json & j, std::string property) {
+        return get_stack_optional<T>(j, property.data());
+    }
+    #endif
+
+    class Anyof {
+        public:
+        Anyof() = default;
+        virtual ~Anyof() = default;
+
+        private:
+        std::string name;
+        std::optional<std::string> size;
+
+        public:
+        const std::string & get_name() const { return name; }
+        std::string & get_mutable_name() { return name; }
+        void set_name(const std::string & value) { this->name = value; }
+
+        const std::optional<std::string> & get_size() const { return size; }
+        std::optional<std::string> & get_mutable_size() { return size; }
+        void set_size(const std::optional<std::string> & value) { this->size = value; }
+    };
+
+    class TopLevel {
+        public:
+        TopLevel() = default;
+        virtual ~TopLevel() = default;
+
+        private:
+        Anyof anyof;
+
+        public:
+        const Anyof & get_anyof() const { return anyof; }
+        Anyof & get_mutable_anyof() { return anyof; }
+        void set_anyof(const Anyof & value) { this->anyof = value; }
+    };
+}
+
+namespace quicktype {
+    void from_json(const json & j, Anyof & x);
+    void to_json(json & j, const Anyof & x);
+
+    void from_json(const json & j, TopLevel & x);
+    void to_json(json & j, const TopLevel & x);
+
+    inline void from_json(const json & j, Anyof& x) {
+        x.set_name(j.at("name").get<std::string>());
+        x.set_size(get_stack_optional<std::string>(j, "size"));
+    }
+
+    inline void to_json(json & j, const Anyof & x) {
+        j = json::object();
+        j["name"] = x.get_name();
+        j["size"] = x.get_size();
+    }
+
+    inline void from_json(const json & j, TopLevel& x) {
+        x.set_anyof(j.at("anyof").get<Anyof>());
+    }
+
+    inline void to_json(json & j, const TopLevel & x) {
+        j = json::object();
+        j["anyof"] = x.get_anyof();
+    }
+}
diff --git a/base/schema-cplusplus/test/inputs/schema/vega-lite.schema/default/quicktype.hpp b/head/schema-cplusplus/test/inputs/schema/vega-lite.schema/default/quicktype.hpp
index 8b7e3c8..6e1635d 100644
--- a/base/schema-cplusplus/test/inputs/schema/vega-lite.schema/default/quicktype.hpp
+++ b/head/schema-cplusplus/test/inputs/schema/vega-lite.schema/default/quicktype.hpp
@@ -2399,7 +2399,7 @@ namespace quicktype {
         private:
         std::optional<double> count;
         std::optional<std::vector<double>> extent;
-        std::optional<std::string> scheme;
+        std::string scheme;
         std::optional<double> step;
 
         public:
@@ -2411,9 +2411,9 @@ namespace quicktype {
         std::optional<std::vector<double>> & get_mutable_extent() { return extent; }
         void set_extent(const std::optional<std::vector<double>> & value) { this->extent = value; }
 
-        const std::optional<std::string> & get_scheme() const { return scheme; }
-        std::optional<std::string> & get_mutable_scheme() { return scheme; }
-        void set_scheme(const std::optional<std::string> & value) { this->scheme = value; }
+        const std::string & get_scheme() const { return scheme; }
+        std::string & get_mutable_scheme() { return scheme; }
+        void set_scheme(const std::string & value) { this->scheme = value; }
 
         const std::optional<double> & get_step() const { return step; }
         std::optional<double> & get_mutable_step() { return step; }
@@ -2979,7 +2979,7 @@ namespace quicktype {
         private:
         std::optional<std::string> element;
         std::string input;
-        std::optional<std::vector<std::string>> options;
+        std::vector<std::string> options;
         std::optional<double> max;
         std::optional<double> min;
         std::optional<double> step;
@@ -2993,9 +2993,9 @@ namespace quicktype {
         std::string & get_mutable_input() { return input; }
         void set_input(const std::string & value) { this->input = value; }
 
-        const std::optional<std::vector<std::string>> & get_options() const { return options; }
-        std::optional<std::vector<std::string>> & get_mutable_options() { return options; }
-        void set_options(const std::optional<std::vector<std::string>> & value) { this->options = value; }
+        const std::vector<std::string> & get_options() const { return options; }
+        std::vector<std::string> & get_mutable_options() { return options; }
+        void set_options(const std::vector<std::string> & value) { this->options = value; }
 
         const std::optional<double> & get_max() const { return max; }
         std::optional<double> & get_mutable_max() { return max; }
@@ -4879,9 +4879,9 @@ namespace quicktype {
 
         private:
         std::optional<DataFormat> format;
-        std::optional<std::string> url;
-        std::optional<Values> values;
-        std::optional<std::string> name;
+        std::string url;
+        Values values;
+        std::string name;
 
         public:
         /**
@@ -4899,9 +4899,9 @@ namespace quicktype {
          * An URL from which to load the data set. Use the `format.type` property
          * to ensure the loaded data is correctly parsed.
          */
-        const std::optional<std::string> & get_url() const { return url; }
-        std::optional<std::string> & get_mutable_url() { return url; }
-        void set_url(const std::optional<std::string> & value) { this->url = value; }
+        const std::string & get_url() const { return url; }
+        std::string & get_mutable_url() { return url; }
+        void set_url(const std::string & value) { this->url = value; }
 
         /**
          * The full data set, included inline. This can be an array of objects or primitive values
@@ -4909,16 +4909,16 @@ namespace quicktype {
          * Arrays of primitive values are ingested as objects with a `data` property. Strings are
          * parsed according to the specified format type.
          */
-        const std::optional<Values> & get_values() const { return values; }
-        std::optional<Values> & get_mutable_values() { return values; }
-        void set_values(const std::optional<Values> & value) { this->values = value; }
+        const Values & get_values() const { return values; }
+        Values & get_mutable_values() { return values; }
+        void set_values(const Values & value) { this->values = value; }
 
         /**
          * Provide a placeholder name and bind data at runtime.
          */
-        const std::optional<std::string> & get_name() const { return name; }
-        std::optional<std::string> & get_mutable_name() { return name; }
-        void set_name(const std::optional<std::string> & value) { this->name = value; }
+        const std::string & get_name() const { return name; }
+        std::string & get_mutable_name() { return name; }
+        void set_name(const std::string & value) { this->name = value; }
     };
 
     /**
@@ -5047,22 +5047,22 @@ namespace quicktype {
         virtual ~Selection() = default;
 
         private:
-        std::shared_ptr<SelectionOperand> selection_not;
-        std::optional<std::vector<SelectionOperand>> selection_and;
-        std::optional<std::vector<SelectionOperand>> selection_or;
+        SelectionOperand selection_not;
+        std::vector<SelectionOperand> selection_and;
+        std::vector<SelectionOperand> selection_or;
 
         public:
-        const std::shared_ptr<SelectionOperand> & get_selection_not() const { return selection_not; }
-        std::shared_ptr<SelectionOperand> & get_mutable_selection_not() { return selection_not; }
-        void set_selection_not(const std::shared_ptr<SelectionOperand> & value) { this->selection_not = value; }
+        const SelectionOperand & get_selection_not() const { return selection_not; }
+        SelectionOperand & get_mutable_selection_not() { return selection_not; }
+        void set_selection_not(const SelectionOperand & value) { this->selection_not = value; }
 
-        const std::optional<std::vector<SelectionOperand>> & get_selection_and() const { return selection_and; }
-        std::optional<std::vector<SelectionOperand>> & get_mutable_selection_and() { return selection_and; }
-        void set_selection_and(const std::optional<std::vector<SelectionOperand>> & value) { this->selection_and = value; }
+        const std::vector<SelectionOperand> & get_selection_and() const { return selection_and; }
+        std::vector<SelectionOperand> & get_mutable_selection_and() { return selection_and; }
+        void set_selection_and(const std::vector<SelectionOperand> & value) { this->selection_and = value; }
 
-        const std::optional<std::vector<SelectionOperand>> & get_selection_or() const { return selection_or; }
-        std::optional<std::vector<SelectionOperand>> & get_mutable_selection_or() { return selection_or; }
-        void set_selection_or(const std::optional<std::vector<SelectionOperand>> & value) { this->selection_or = value; }
+        const std::vector<SelectionOperand> & get_selection_or() const { return selection_or; }
+        std::vector<SelectionOperand> & get_mutable_selection_or() { return selection_or; }
+        void set_selection_or(const std::vector<SelectionOperand> & value) { this->selection_or = value; }
     };
 
     using Day = std::variant<double, std::string>;
@@ -5212,44 +5212,44 @@ namespace quicktype {
         virtual ~Predicate() = default;
 
         private:
-        std::shared_ptr<LogicalOperandPredicate> predicate_not;
-        std::optional<std::vector<LogicalOperandPredicate>> predicate_and;
-        std::optional<std::vector<LogicalOperandPredicate>> predicate_or;
-        std::optional<Equal> equal;
-        std::optional<std::string> field;
+        LogicalOperandPredicate predicate_not;
+        std::vector<LogicalOperandPredicate> predicate_and;
+        std::vector<LogicalOperandPredicate> predicate_or;
+        Equal equal;
+        std::string field;
         std::optional<TimeUnit> time_unit;
-        std::optional<std::vector<RangeElement>> range;
-        std::optional<std::vector<Equal>> one_of;
-        std::shared_ptr<SelectionOperand> selection;
+        std::vector<RangeElement> range;
+        std::vector<Equal> one_of;
+        SelectionOperand selection;
 
         public:
-        const std::shared_ptr<LogicalOperandPredicate> & get_predicate_not() const { return predicate_not; }
-        std::shared_ptr<LogicalOperandPredicate> & get_mutable_predicate_not() { return predicate_not; }
-        void set_predicate_not(const std::shared_ptr<LogicalOperandPredicate> & value) { this->predicate_not = value; }
+        const LogicalOperandPredicate & get_predicate_not() const { return predicate_not; }
+        LogicalOperandPredicate & get_mutable_predicate_not() { return predicate_not; }
+        void set_predicate_not(const LogicalOperandPredicate & value) { this->predicate_not = value; }
 
-        const std::optional<std::vector<LogicalOperandPredicate>> & get_predicate_and() const { return predicate_and; }
-        std::optional<std::vector<LogicalOperandPredicate>> & get_mutable_predicate_and() { return predicate_and; }
-        void set_predicate_and(const std::optional<std::vector<LogicalOperandPredicate>> & value) { this->predicate_and = value; }
+        const std::vector<LogicalOperandPredicate> & get_predicate_and() const { return predicate_and; }
+        std::vector<LogicalOperandPredicate> & get_mutable_predicate_and() { return predicate_and; }
+        void set_predicate_and(const std::vector<LogicalOperandPredicate> & value) { this->predicate_and = value; }
 
-        const std::optional<std::vector<LogicalOperandPredicate>> & get_predicate_or() const { return predicate_or; }
-        std::optional<std::vector<LogicalOperandPredicate>> & get_mutable_predicate_or() { return predicate_or; }
-        void set_predicate_or(const std::optional<std::vector<LogicalOperandPredicate>> & value) { this->predicate_or = value; }
+        const std::vector<LogicalOperandPredicate> & get_predicate_or() const { return predicate_or; }
+        std::vector<LogicalOperandPredicate> & get_mutable_predicate_or() { return predicate_or; }
+        void set_predicate_or(const std::vector<LogicalOperandPredicate> & value) { this->predicate_or = value; }
 
         /**
          * The value that the field should be equal to.
          */
-        const std::optional<Equal> & get_equal() const { return equal; }
-        std::optional<Equal> & get_mutable_equal() { return equal; }
-        void set_equal(const std::optional<Equal> & value) { this->equal = value; }
+        const Equal & get_equal() const { return equal; }
+        Equal & get_mutable_equal() { return equal; }
+        void set_equal(const Equal & value) { this->equal = value; }
 
         /**
          * Field to be filtered.
          *
          * Field to be filtered
          */
-        const std::optional<std::string> & get_field() const { return field; }
-        std::optional<std::string> & get_mutable_field() { return field; }
-        void set_field(const std::optional<std::string> & value) { this->field = value; }
+        const std::string & get_field() const { return field; }
+        std::string & get_mutable_field() { return field; }
+        void set_field(const std::string & value) { this->field = value; }
 
         /**
          * Time unit for the field to be filtered.
@@ -5264,24 +5264,24 @@ namespace quicktype {
          * An array of inclusive minimum and maximum values
          * for a field value of a data item to be included in the filtered data.
          */
-        const std::optional<std::vector<RangeElement>> & get_range() const { return range; }
-        std::optional<std::vector<RangeElement>> & get_mutable_range() { return range; }
-        void set_range(const std::optional<std::vector<RangeElement>> & value) { this->range = value; }
+        const std::vector<RangeElement> & get_range() const { return range; }
+        std::vector<RangeElement> & get_mutable_range() { return range; }
+        void set_range(const std::vector<RangeElement> & value) { this->range = value; }
 
         /**
          * A set of values that the `field`'s value should be a member of,
          * for a data item included in the filtered data.
          */
-        const std::optional<std::vector<Equal>> & get_one_of() const { return one_of; }
-        std::optional<std::vector<Equal>> & get_mutable_one_of() { return one_of; }
-        void set_one_of(const std::optional<std::vector<Equal>> & value) { this->one_of = value; }
+        const std::vector<Equal> & get_one_of() const { return one_of; }
+        std::vector<Equal> & get_mutable_one_of() { return one_of; }
+        void set_one_of(const std::vector<Equal> & value) { this->one_of = value; }
 
         /**
          * Filter using a selection name.
          */
-        const std::shared_ptr<SelectionOperand> & get_selection() const { return selection; }
-        std::shared_ptr<SelectionOperand> & get_mutable_selection() { return selection; }
-        void set_selection(const std::shared_ptr<SelectionOperand> & value) { this->selection = value; }
+        const SelectionOperand & get_selection() const { return selection; }
+        SelectionOperand & get_mutable_selection() { return selection; }
+        void set_selection(const SelectionOperand & value) { this->selection = value; }
     };
 
     using ConditionalValueDefValue = std::variant<bool, double, std::string>;
@@ -5292,14 +5292,14 @@ namespace quicktype {
         virtual ~ConditionalValueDef() = default;
 
         private:
-        std::shared_ptr<LogicalOperandPredicate> test;
+        LogicalOperandPredicate test;
         ConditionalValueDefValue value;
-        std::shared_ptr<SelectionOperand> selection;
+        SelectionOperand selection;
 
         public:
-        const std::shared_ptr<LogicalOperandPredicate> & get_test() const { return test; }
-        std::shared_ptr<LogicalOperandPredicate> & get_mutable_test() { return test; }
-        void set_test(const std::shared_ptr<LogicalOperandPredicate> & value) { this->test = value; }
+        const LogicalOperandPredicate & get_test() const { return test; }
+        LogicalOperandPredicate & get_mutable_test() { return test; }
+        void set_test(const LogicalOperandPredicate & value) { this->test = value; }
 
         /**
          * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
@@ -5313,9 +5313,9 @@ namespace quicktype {
          * A [selection name](selection.html), or a series of [composed
          * selections](selection.html#compose).
          */
-        const std::shared_ptr<SelectionOperand> & get_selection() const { return selection; }
-        std::shared_ptr<SelectionOperand> & get_mutable_selection() { return selection; }
-        void set_selection(const std::shared_ptr<SelectionOperand> & value) { this->selection = value; }
+        const SelectionOperand & get_selection() const { return selection; }
+        SelectionOperand & get_mutable_selection() { return selection; }
+        void set_selection(const SelectionOperand & value) { this->selection = value; }
     };
 
     enum class RepeatEnum : int { ROW, COLUMN };
@@ -5960,9 +5960,9 @@ namespace quicktype {
         virtual ~ConditionalPredicateMarkPropFieldDefClass() = default;
 
         private:
-        std::shared_ptr<LogicalOperandPredicate> test;
-        std::optional<ConditionalValueDefValue> value;
-        std::shared_ptr<SelectionOperand> selection;
+        LogicalOperandPredicate test;
+        ConditionalValueDefValue value;
+        SelectionOperand selection;
         std::optional<AggregateOp> aggregate;
         std::optional<Bin> bin;
         std::optional<Field> field;
@@ -5970,28 +5970,28 @@ namespace quicktype {
         std::optional<Scale> scale;
         SortUnion sort;
         std::optional<TimeUnit> time_unit;
-        std::optional<Type> type;
+        Type type;
 
         public:
-        const std::shared_ptr<LogicalOperandPredicate> & get_test() const { return test; }
-        std::shared_ptr<LogicalOperandPredicate> & get_mutable_test() { return test; }
-        void set_test(const std::shared_ptr<LogicalOperandPredicate> & value) { this->test = value; }
+        const LogicalOperandPredicate & get_test() const { return test; }
+        LogicalOperandPredicate & get_mutable_test() { return test; }
+        void set_test(const LogicalOperandPredicate & value) { this->test = value; }
 
         /**
          * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
          * `0` to `1` for opacity).
          */
-        const std::optional<ConditionalValueDefValue> & get_value() const { return value; }
-        std::optional<ConditionalValueDefValue> & get_mutable_value() { return value; }
-        void set_value(const std::optional<ConditionalValueDefValue> & value) { this->value = value; }
+        const ConditionalValueDefValue & get_value() const { return value; }
+        ConditionalValueDefValue & get_mutable_value() { return value; }
+        void set_value(const ConditionalValueDefValue & value) { this->value = value; }
 
         /**
          * A [selection name](selection.html), or a series of [composed
          * selections](selection.html#compose).
          */
-        const std::shared_ptr<SelectionOperand> & get_selection() const { return selection; }
-        std::shared_ptr<SelectionOperand> & get_mutable_selection() { return selection; }
-        void set_selection(const std::shared_ptr<SelectionOperand> & value) { this->selection = value; }
+        const SelectionOperand & get_selection() const { return selection; }
+        SelectionOperand & get_mutable_selection() { return selection; }
+        void set_selection(const SelectionOperand & value) { this->selection = value; }
 
         /**
          * Aggregation function for the field
@@ -6077,9 +6077,9 @@ namespace quicktype {
          * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
          * [geographic projection](projection.html) is applied.
          */
-        const std::optional<Type> & get_type() const { return type; }
-        std::optional<Type> & get_mutable_type() { return type; }
-        void set_type(const std::optional<Type> & value) { this->type = value; }
+        const Type & get_type() const { return type; }
+        Type & get_mutable_type() { return type; }
+        void set_type(const Type & value) { this->type = value; }
     };
 
     using ColorCondition = std::variant<std::vector<ConditionalValueDef>, ConditionalPredicateMarkPropFieldDefClass>;
@@ -6141,7 +6141,7 @@ namespace quicktype {
         std::optional<Scale> scale;
         SortUnion sort;
         std::optional<TimeUnit> time_unit;
-        std::optional<Type> type;
+        Type type;
         std::optional<ConditionalValueDefValue> value;
 
         public:
@@ -6242,9 +6242,9 @@ namespace quicktype {
          * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
          * [geographic projection](projection.html) is applied.
          */
-        const std::optional<Type> & get_type() const { return type; }
-        std::optional<Type> & get_mutable_type() { return type; }
-        void set_type(const std::optional<Type> & value) { this->type = value; }
+        const Type & get_type() const { return type; }
+        Type & get_mutable_type() { return type; }
+        void set_type(const Type & value) { this->type = value; }
 
         /**
          * A constant value in visual domain.
@@ -6489,35 +6489,35 @@ namespace quicktype {
         virtual ~ConditionalPredicateFieldDefClass() = default;
 
         private:
-        std::shared_ptr<LogicalOperandPredicate> test;
-        std::optional<ConditionalValueDefValue> value;
-        std::shared_ptr<SelectionOperand> selection;
+        LogicalOperandPredicate test;
+        ConditionalValueDefValue value;
+        SelectionOperand selection;
         std::optional<AggregateOp> aggregate;
         std::optional<Bin> bin;
         std::optional<Field> field;
         std::optional<TimeUnit> time_unit;
-        std::optional<Type> type;
+        Type type;
 
         public:
-        const std::shared_ptr<LogicalOperandPredicate> & get_test() const { return test; }
-        std::shared_ptr<LogicalOperandPredicate> & get_mutable_test() { return test; }
-        void set_test(const std::shared_ptr<LogicalOperandPredicate> & value) { this->test = value; }
+        const LogicalOperandPredicate & get_test() const { return test; }
+        LogicalOperandPredicate & get_mutable_test() { return test; }
+        void set_test(const LogicalOperandPredicate & value) { this->test = value; }
 
         /**
          * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
          * `0` to `1` for opacity).
          */
-        const std::optional<ConditionalValueDefValue> & get_value() const { return value; }
-        std::optional<ConditionalValueDefValue> & get_mutable_value() { return value; }
-        void set_value(const std::optional<ConditionalValueDefValue> & value) { this->value = value; }
+        const ConditionalValueDefValue & get_value() const { return value; }
+        ConditionalValueDefValue & get_mutable_value() { return value; }
+        void set_value(const ConditionalValueDefValue & value) { this->value = value; }
 
         /**
          * A [selection name](selection.html), or a series of [composed
          * selections](selection.html#compose).
          */
-        const std::shared_ptr<SelectionOperand> & get_selection() const { return selection; }
-        std::shared_ptr<SelectionOperand> & get_mutable_selection() { return selection; }
-        void set_selection(const std::shared_ptr<SelectionOperand> & value) { this->selection = value; }
+        const SelectionOperand & get_selection() const { return selection; }
+        SelectionOperand & get_mutable_selection() { return selection; }
+        void set_selection(const SelectionOperand & value) { this->selection = value; }
 
         /**
          * Aggregation function for the field
@@ -6572,9 +6572,9 @@ namespace quicktype {
          * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
          * [geographic projection](projection.html) is applied.
          */
-        const std::optional<Type> & get_type() const { return type; }
-        std::optional<Type> & get_mutable_type() { return type; }
-        void set_type(const std::optional<Type> & value) { this->type = value; }
+        const Type & get_type() const { return type; }
+        Type & get_mutable_type() { return type; }
+        void set_type(const Type & value) { this->type = value; }
     };
 
     using HrefCondition = std::variant<std::vector<ConditionalValueDef>, ConditionalPredicateFieldDefClass>;
@@ -6606,7 +6606,7 @@ namespace quicktype {
         std::optional<HrefCondition> condition;
         std::optional<Field> field;
         std::optional<TimeUnit> time_unit;
-        std::optional<Type> type;
+        Type type;
         std::optional<ConditionalValueDefValue> value;
 
         public:
@@ -6676,9 +6676,9 @@ namespace quicktype {
          * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
          * [geographic projection](projection.html) is applied.
          */
-        const std::optional<Type> & get_type() const { return type; }
-        std::optional<Type> & get_mutable_type() { return type; }
-        void set_type(const std::optional<Type> & value) { this->type = value; }
+        const Type & get_type() const { return type; }
+        Type & get_mutable_type() { return type; }
+        void set_type(const Type & value) { this->type = value; }
 
         /**
          * A constant value in visual domain.
@@ -6774,36 +6774,36 @@ namespace quicktype {
         virtual ~ConditionalPredicateTextFieldDefClass() = default;
 
         private:
-        std::shared_ptr<LogicalOperandPredicate> test;
-        std::optional<ConditionalValueDefValue> value;
-        std::shared_ptr<SelectionOperand> selection;
+        LogicalOperandPredicate test;
+        ConditionalValueDefValue value;
+        SelectionOperand selection;
         std::optional<AggregateOp> aggregate;
         std::optional<Bin> bin;
         std::optional<Field> field;
         std::optional<std::string> format;
         std::optional<TimeUnit> time_unit;
-        std::optional<Type> type;
+        Type type;
 
         public:
-        const std::shared_ptr<LogicalOperandPredicate> & get_test() const { return test; }
-        std::shared_ptr<LogicalOperandPredicate> & get_mutable_test() { return test; }
-        void set_test(const std::shared_ptr<LogicalOperandPredicate> & value) { this->test = value; }
+        const LogicalOperandPredicate & get_test() const { return test; }
+        LogicalOperandPredicate & get_mutable_test() { return test; }
+        void set_test(const LogicalOperandPredicate & value) { this->test = value; }
 
         /**
          * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
          * `0` to `1` for opacity).
          */
-        const std::optional<ConditionalValueDefValue> & get_value() const { return value; }
-        std::optional<ConditionalValueDefValue> & get_mutable_value() { return value; }
-        void set_value(const std::optional<ConditionalValueDefValue> & value) { this->value = value; }
+        const ConditionalValueDefValue & get_value() const { return value; }
+        ConditionalValueDefValue & get_mutable_value() { return value; }
+        void set_value(const ConditionalValueDefValue & value) { this->value = value; }
 
         /**
          * A [selection name](selection.html), or a series of [composed
          * selections](selection.html#compose).
          */
-        const std::shared_ptr<SelectionOperand> & get_selection() const { return selection; }
-        std::shared_ptr<SelectionOperand> & get_mutable_selection() { return selection; }
-        void set_selection(const std::shared_ptr<SelectionOperand> & value) { this->selection = value; }
+        const SelectionOperand & get_selection() const { return selection; }
+        SelectionOperand & get_mutable_selection() { return selection; }
+        void set_selection(const SelectionOperand & value) { this->selection = value; }
 
         /**
          * Aggregation function for the field
@@ -6866,9 +6866,9 @@ namespace quicktype {
          * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
          * [geographic projection](projection.html) is applied.
          */
-        const std::optional<Type> & get_type() const { return type; }
-        std::optional<Type> & get_mutable_type() { return type; }
-        void set_type(const std::optional<Type> & value) { this->type = value; }
+        const Type & get_type() const { return type; }
+        Type & get_mutable_type() { return type; }
+        void set_type(const Type & value) { this->type = value; }
     };
 
     using TextCondition = std::variant<std::vector<ConditionalValueDef>, ConditionalPredicateTextFieldDefClass>;
@@ -6903,7 +6903,7 @@ namespace quicktype {
         std::optional<Field> field;
         std::optional<std::string> format;
         std::optional<TimeUnit> time_unit;
-        std::optional<Type> type;
+        Type type;
         std::optional<ConditionalValueDefValue> value;
 
         public:
@@ -6981,9 +6981,9 @@ namespace quicktype {
          * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
          * [geographic projection](projection.html) is applied.
          */
-        const std::optional<Type> & get_type() const { return type; }
-        std::optional<Type> & get_mutable_type() { return type; }
-        void set_type(const std::optional<Type> & value) { this->type = value; }
+        const Type & get_type() const { return type; }
+        Type & get_mutable_type() { return type; }
+        void set_type(const Type & value) { this->type = value; }
 
         /**
          * A constant value in visual domain.
@@ -7283,8 +7283,8 @@ namespace quicktype {
         SortUnion sort;
         std::optional<StackOffset> stack;
         std::optional<TimeUnit> time_unit;
-        std::optional<Type> type;
-        std::optional<ConditionalValueDefValue> value;
+        Type type;
+        ConditionalValueDefValue value;
 
         public:
         /**
@@ -7396,17 +7396,17 @@ namespace quicktype {
          * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
          * [geographic projection](projection.html) is applied.
          */
-        const std::optional<Type> & get_type() const { return type; }
-        std::optional<Type> & get_mutable_type() { return type; }
-        void set_type(const std::optional<Type> & value) { this->type = value; }
+        const Type & get_type() const { return type; }
+        Type & get_mutable_type() { return type; }
+        void set_type(const Type & value) { this->type = value; }
 
         /**
          * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
          * `0` to `1` for opacity).
          */
-        const std::optional<ConditionalValueDefValue> & get_value() const { return value; }
-        std::optional<ConditionalValueDefValue> & get_mutable_value() { return value; }
-        void set_value(const std::optional<ConditionalValueDefValue> & value) { this->value = value; }
+        const ConditionalValueDefValue & get_value() const { return value; }
+        ConditionalValueDefValue & get_mutable_value() { return value; }
+        void set_value(const ConditionalValueDefValue & value) { this->value = value; }
     };
 
     /**
@@ -7428,8 +7428,8 @@ namespace quicktype {
         std::optional<Bin> bin;
         std::optional<Field> field;
         std::optional<TimeUnit> time_unit;
-        std::optional<Type> type;
-        std::optional<ConditionalValueDefValue> value;
+        Type type;
+        ConditionalValueDefValue value;
 
         public:
         /**
@@ -7485,17 +7485,17 @@ namespace quicktype {
          * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
          * [geographic projection](projection.html) is applied.
          */
-        const std::optional<Type> & get_type() const { return type; }
-        std::optional<Type> & get_mutable_type() { return type; }
-        void set_type(const std::optional<Type> & value) { this->type = value; }
+        const Type & get_type() const { return type; }
+        Type & get_mutable_type() { return type; }
+        void set_type(const Type & value) { this->type = value; }
 
         /**
          * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
          * `0` to `1` for opacity).
          */
-        const std::optional<ConditionalValueDefValue> & get_value() const { return value; }
-        std::optional<ConditionalValueDefValue> & get_mutable_value() { return value; }
-        void set_value(const std::optional<ConditionalValueDefValue> & value) { this->value = value; }
+        const ConditionalValueDefValue & get_value() const { return value; }
+        ConditionalValueDefValue & get_mutable_value() { return value; }
+        void set_value(const ConditionalValueDefValue & value) { this->value = value; }
     };
 
     /**
@@ -8756,16 +8756,16 @@ namespace quicktype {
         virtual ~Transform() = default;
 
         private:
-        std::shared_ptr<LogicalOperandPredicate> filter;
+        LogicalOperandPredicate filter;
         std::optional<Style> as;
-        std::optional<std::string> calculate;
+        std::string calculate;
         std::optional<std::string> transform_default;
-        std::optional<LookupData> from;
-        std::optional<std::string> lookup;
-        std::optional<Bin> bin;
-        std::optional<std::string> field;
-        std::optional<TimeUnit> time_unit;
-        std::optional<std::vector<AggregatedFieldDef>> aggregate;
+        LookupData from;
+        std::string lookup;
+        Bin bin;
+        std::string field;
+        TimeUnit time_unit;
+        std::vector<AggregatedFieldDef> aggregate;
         std::optional<std::vector<std::string>> groupby;
 
         public:
@@ -8779,9 +8779,9 @@ namespace quicktype {
          * (3) a [selection predicate](filter.html#selection-predicate);
          * or (4) a logical operand that combines (1), (2), or (3).
          */
-        const std::shared_ptr<LogicalOperandPredicate> & get_filter() const { return filter; }
-        std::shared_ptr<LogicalOperandPredicate> & get_mutable_filter() { return filter; }
-        void set_filter(const std::shared_ptr<LogicalOperandPredicate> & value) { this->filter = value; }
+        const LogicalOperandPredicate & get_filter() const { return filter; }
+        LogicalOperandPredicate & get_mutable_filter() { return filter; }
+        void set_filter(const LogicalOperandPredicate & value) { this->filter = value; }
 
         /**
          * The field for storing the computed formula value.
@@ -8803,9 +8803,9 @@ namespace quicktype {
          * A [expression](types.html#expression) string. Use the variable `datum` to refer to the
          * current data object.
          */
-        const std::optional<std::string> & get_calculate() const { return calculate; }
-        std::optional<std::string> & get_mutable_calculate() { return calculate; }
-        void set_calculate(const std::optional<std::string> & value) { this->calculate = value; }
+        const std::string & get_calculate() const { return calculate; }
+        std::string & get_mutable_calculate() { return calculate; }
+        void set_calculate(const std::string & value) { this->calculate = value; }
 
         /**
          * The default value to use if lookup fails.
@@ -8819,46 +8819,46 @@ namespace quicktype {
         /**
          * Secondary data reference.
          */
-        const std::optional<LookupData> & get_from() const { return from; }
-        std::optional<LookupData> & get_mutable_from() { return from; }
-        void set_from(const std::optional<LookupData> & value) { this->from = value; }
+        const LookupData & get_from() const { return from; }
+        LookupData & get_mutable_from() { return from; }
+        void set_from(const LookupData & value) { this->from = value; }
 
         /**
          * Key in primary data source.
          */
-        const std::optional<std::string> & get_lookup() const { return lookup; }
-        std::optional<std::string> & get_mutable_lookup() { return lookup; }
-        void set_lookup(const std::optional<std::string> & value) { this->lookup = value; }
+        const std::string & get_lookup() const { return lookup; }
+        std::string & get_mutable_lookup() { return lookup; }
+        void set_lookup(const std::string & value) { this->lookup = value; }
 
         /**
          * An object indicating bin properties, or simply `true` for using default bin parameters.
          */
-        const std::optional<Bin> & get_bin() const { return bin; }
-        std::optional<Bin> & get_mutable_bin() { return bin; }
-        void set_bin(const std::optional<Bin> & value) { this->bin = value; }
+        const Bin & get_bin() const { return bin; }
+        Bin & get_mutable_bin() { return bin; }
+        void set_bin(const Bin & value) { this->bin = value; }
 
         /**
          * The data field to bin.
          *
          * The data field to apply time unit.
          */
-        const std::optional<std::string> & get_field() const { return field; }
-        std::optional<std::string> & get_mutable_field() { return field; }
-        void set_field(const std::optional<std::string> & value) { this->field = value; }
+        const std::string & get_field() const { return field; }
+        std::string & get_mutable_field() { return field; }
+        void set_field(const std::string & value) { this->field = value; }
 
         /**
          * The timeUnit.
          */
-        const std::optional<TimeUnit> & get_time_unit() const { return time_unit; }
-        std::optional<TimeUnit> & get_mutable_time_unit() { return time_unit; }
-        void set_time_unit(const std::optional<TimeUnit> & value) { this->time_unit = value; }
+        const TimeUnit & get_time_unit() const { return time_unit; }
+        TimeUnit & get_mutable_time_unit() { return time_unit; }
+        void set_time_unit(const TimeUnit & value) { this->time_unit = value; }
 
         /**
          * Array of objects that define fields to aggregate.
          */
-        const std::optional<std::vector<AggregatedFieldDef>> & get_aggregate() const { return aggregate; }
-        std::optional<std::vector<AggregatedFieldDef>> & get_mutable_aggregate() { return aggregate; }
-        void set_aggregate(const std::optional<std::vector<AggregatedFieldDef>> & value) { this->aggregate = value; }
+        const std::vector<AggregatedFieldDef> & get_aggregate() const { return aggregate; }
+        std::vector<AggregatedFieldDef> & get_mutable_aggregate() { return aggregate; }
+        void set_aggregate(const std::vector<AggregatedFieldDef> & value) { this->aggregate = value; }
 
         /**
          * The data fields to group by. If not specified, a single group containing all data objects
@@ -8881,14 +8881,14 @@ namespace quicktype {
         std::optional<Data> data;
         std::optional<std::string> description;
         std::optional<double> height;
-        std::optional<std::vector<LayerSpec>> layer;
+        std::vector<LayerSpec> layer;
         std::optional<std::string> name;
         std::optional<Resolve> resolve;
         std::optional<Title> title;
         std::optional<std::vector<Transform>> transform;
         std::optional<double> width;
-        std::optional<Encoding> encoding;
-        std::optional<AnyMark> mark;
+        Encoding encoding;
+        AnyMark mark;
         std::optional<Projection> projection;
         std::optional<std::map<std::string, SelectionDef>> selection;
 
@@ -8936,9 +8936,9 @@ namespace quicktype {
          * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
          * layering facet specifications is not allowed.
          */
-        const std::optional<std::vector<LayerSpec>> & get_layer() const { return layer; }
-        std::optional<std::vector<LayerSpec>> & get_mutable_layer() { return layer; }
-        void set_layer(const std::optional<std::vector<LayerSpec>> & value) { this->layer = value; }
+        const std::vector<LayerSpec> & get_layer() const { return layer; }
+        std::vector<LayerSpec> & get_mutable_layer() { return layer; }
+        void set_layer(const std::vector<LayerSpec> & value) { this->layer = value; }
 
         /**
          * Name of the visualization for later reference.
@@ -8997,9 +8997,9 @@ namespace quicktype {
         /**
          * A key-value mapping between encoding channels and definition of fields.
          */
-        const std::optional<Encoding> & get_encoding() const { return encoding; }
-        std::optional<Encoding> & get_mutable_encoding() { return encoding; }
-        void set_encoding(const std::optional<Encoding> & value) { this->encoding = value; }
+        const Encoding & get_encoding() const { return encoding; }
+        Encoding & get_mutable_encoding() { return encoding; }
+        void set_encoding(const Encoding & value) { this->encoding = value; }
 
         /**
          * A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
@@ -9007,9 +9007,9 @@ namespace quicktype {
          * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
          * object](mark.html#mark-def).
          */
-        const std::optional<AnyMark> & get_mark() const { return mark; }
-        std::optional<AnyMark> & get_mutable_mark() { return mark; }
-        void set_mark(const std::optional<AnyMark> & value) { this->mark = value; }
+        const AnyMark & get_mark() const { return mark; }
+        AnyMark & get_mutable_mark() { return mark; }
+        void set_mark(const AnyMark & value) { this->mark = value; }
 
         /**
          * An object defining properties of geographic projection.
@@ -9070,21 +9070,21 @@ namespace quicktype {
         std::optional<Data> data;
         std::optional<std::string> description;
         std::optional<double> height;
-        std::optional<std::vector<LayerSpec>> layer;
+        std::vector<LayerSpec> layer;
         std::optional<std::string> name;
         std::optional<Resolve> resolve;
         std::optional<Title> title;
         std::optional<std::vector<Transform>> transform;
         std::optional<double> width;
-        std::optional<Encoding> encoding;
-        std::optional<AnyMark> mark;
+        Encoding encoding;
+        AnyMark mark;
         std::optional<Projection> projection;
         std::optional<std::map<std::string, SelectionDef>> selection;
-        std::optional<FacetMapping> facet;
+        FacetMapping facet;
         std::shared_ptr<Spec> spec;
-        std::optional<Repeat> repeat;
-        std::optional<std::vector<Spec>> vconcat;
-        std::optional<std::vector<Spec>> hconcat;
+        Repeat repeat;
+        std::vector<Spec> vconcat;
+        std::vector<Spec> hconcat;
 
         public:
         /**
@@ -9130,9 +9130,9 @@ namespace quicktype {
          * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
          * layering facet specifications is not allowed.
          */
-        const std::optional<std::vector<LayerSpec>> & get_layer() const { return layer; }
-        std::optional<std::vector<LayerSpec>> & get_mutable_layer() { return layer; }
-        void set_layer(const std::optional<std::vector<LayerSpec>> & value) { this->layer = value; }
+        const std::vector<LayerSpec> & get_layer() const { return layer; }
+        std::vector<LayerSpec> & get_mutable_layer() { return layer; }
+        void set_layer(const std::vector<LayerSpec> & value) { this->layer = value; }
 
         /**
          * Name of the visualization for later reference.
@@ -9199,9 +9199,9 @@ namespace quicktype {
         /**
          * A key-value mapping between encoding channels and definition of fields.
          */
-        const std::optional<Encoding> & get_encoding() const { return encoding; }
-        std::optional<Encoding> & get_mutable_encoding() { return encoding; }
-        void set_encoding(const std::optional<Encoding> & value) { this->encoding = value; }
+        const Encoding & get_encoding() const { return encoding; }
+        Encoding & get_mutable_encoding() { return encoding; }
+        void set_encoding(const Encoding & value) { this->encoding = value; }
 
         /**
          * A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
@@ -9209,9 +9209,9 @@ namespace quicktype {
          * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
          * object](mark.html#mark-def).
          */
-        const std::optional<AnyMark> & get_mark() const { return mark; }
-        std::optional<AnyMark> & get_mutable_mark() { return mark; }
-        void set_mark(const std::optional<AnyMark> & value) { this->mark = value; }
+        const AnyMark & get_mark() const { return mark; }
+        AnyMark & get_mutable_mark() { return mark; }
+        void set_mark(const AnyMark & value) { this->mark = value; }
 
         /**
          * An object defining properties of geographic projection.
@@ -9234,9 +9234,9 @@ namespace quicktype {
          * An object that describes mappings between `row` and `column` channels and their field
          * definitions.
          */
-        const std::optional<FacetMapping> & get_facet() const { return facet; }
-        std::optional<FacetMapping> & get_mutable_facet() { return facet; }
-        void set_facet(const std::optional<FacetMapping> & value) { this->facet = value; }
+        const FacetMapping & get_facet() const { return facet; }
+        FacetMapping & get_mutable_facet() { return facet; }
+        void set_facet(const FacetMapping & value) { this->facet = value; }
 
         /**
          * A specification of the view that gets faceted.
@@ -9249,23 +9249,23 @@ namespace quicktype {
          * An object that describes what fields should be repeated into views that are laid out as a
          * `row` or `column`.
          */
-        const std::optional<Repeat> & get_repeat() const { return repeat; }
-        std::optional<Repeat> & get_mutable_repeat() { return repeat; }
-        void set_repeat(const std::optional<Repeat> & value) { this->repeat = value; }
+        const Repeat & get_repeat() const { return repeat; }
+        Repeat & get_mutable_repeat() { return repeat; }
+        void set_repeat(const Repeat & value) { this->repeat = value; }
 
         /**
          * A list of views that should be concatenated and put into a column.
          */
-        const std::optional<std::vector<Spec>> & get_vconcat() const { return vconcat; }
-        std::optional<std::vector<Spec>> & get_mutable_vconcat() { return vconcat; }
-        void set_vconcat(const std::optional<std::vector<Spec>> & value) { this->vconcat = value; }
+        const std::vector<Spec> & get_vconcat() const { return vconcat; }
+        std::vector<Spec> & get_mutable_vconcat() { return vconcat; }
+        void set_vconcat(const std::vector<Spec> & value) { this->vconcat = value; }
 
         /**
          * A list of views that should be concatenated and put into a row.
          */
-        const std::optional<std::vector<Spec>> & get_hconcat() const { return hconcat; }
-        std::optional<std::vector<Spec>> & get_mutable_hconcat() { return hconcat; }
-        void set_hconcat(const std::optional<std::vector<Spec>> & value) { this->hconcat = value; }
+        const std::vector<Spec> & get_hconcat() const { return hconcat; }
+        std::vector<Spec> & get_mutable_hconcat() { return hconcat; }
+        void set_hconcat(const std::vector<Spec> & value) { this->hconcat = value; }
     };
 
     class TopLevel {
@@ -9280,9 +9280,9 @@ namespace quicktype {
         std::optional<Config> config;
         std::optional<Data> data;
         std::optional<std::string> description;
-        std::optional<EncodingWithFacet> encoding;
+        EncodingWithFacet encoding;
         std::optional<double> height;
-        std::optional<AnyMark> mark;
+        AnyMark mark;
         std::optional<std::string> name;
         std::optional<Padding> padding;
         std::optional<Projection> projection;
@@ -9290,13 +9290,13 @@ namespace quicktype {
         std::optional<Title> title;
         std::optional<std::vector<Transform>> transform;
         std::optional<double> width;
-        std::optional<std::vector<LayerSpec>> layer;
+        std::vector<LayerSpec> layer;
         std::optional<Resolve> resolve;
-        std::optional<FacetMapping> facet;
+        FacetMapping facet;
         std::shared_ptr<Spec> spec;
-        std::optional<Repeat> repeat;
-        std::optional<std::vector<Spec>> vconcat;
-        std::optional<std::vector<Spec>> hconcat;
+        Repeat repeat;
+        std::vector<Spec> vconcat;
+        std::vector<Spec> hconcat;
 
         public:
         /**
@@ -9356,9 +9356,9 @@ namespace quicktype {
         /**
          * A key-value mapping between encoding channels and definition of fields.
          */
-        const std::optional<EncodingWithFacet> & get_encoding() const { return encoding; }
-        std::optional<EncodingWithFacet> & get_mutable_encoding() { return encoding; }
-        void set_encoding(const std::optional<EncodingWithFacet> & value) { this->encoding = value; }
+        const EncodingWithFacet & get_encoding() const { return encoding; }
+        EncodingWithFacet & get_mutable_encoding() { return encoding; }
+        void set_encoding(const EncodingWithFacet & value) { this->encoding = value; }
 
         /**
          * The height of a visualization.
@@ -9389,9 +9389,9 @@ namespace quicktype {
          * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
          * object](mark.html#mark-def).
          */
-        const std::optional<AnyMark> & get_mark() const { return mark; }
-        std::optional<AnyMark> & get_mutable_mark() { return mark; }
-        void set_mark(const std::optional<AnyMark> & value) { this->mark = value; }
+        const AnyMark & get_mark() const { return mark; }
+        AnyMark & get_mutable_mark() { return mark; }
+        void set_mark(const AnyMark & value) { this->mark = value; }
 
         /**
          * Name of the visualization for later reference.
@@ -9475,9 +9475,9 @@ namespace quicktype {
          * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
          * layering facet specifications is not allowed.
          */
-        const std::optional<std::vector<LayerSpec>> & get_layer() const { return layer; }
-        std::optional<std::vector<LayerSpec>> & get_mutable_layer() { return layer; }
-        void set_layer(const std::optional<std::vector<LayerSpec>> & value) { this->layer = value; }
+        const std::vector<LayerSpec> & get_layer() const { return layer; }
+        std::vector<LayerSpec> & get_mutable_layer() { return layer; }
+        void set_layer(const std::vector<LayerSpec> & value) { this->layer = value; }
 
         /**
          * Scale, axis, and legend resolutions for layers.
@@ -9498,9 +9498,9 @@ namespace quicktype {
          * An object that describes mappings between `row` and `column` channels and their field
          * definitions.
          */
-        const std::optional<FacetMapping> & get_facet() const { return facet; }
-        std::optional<FacetMapping> & get_mutable_facet() { return facet; }
-        void set_facet(const std::optional<FacetMapping> & value) { this->facet = value; }
+        const FacetMapping & get_facet() const { return facet; }
+        FacetMapping & get_mutable_facet() { return facet; }
+        void set_facet(const FacetMapping & value) { this->facet = value; }
 
         /**
          * A specification of the view that gets faceted.
@@ -9513,23 +9513,23 @@ namespace quicktype {
          * An object that describes what fields should be repeated into views that are laid out as a
          * `row` or `column`.
          */
-        const std::optional<Repeat> & get_repeat() const { return repeat; }
-        std::optional<Repeat> & get_mutable_repeat() { return repeat; }
-        void set_repeat(const std::optional<Repeat> & value) { this->repeat = value; }
+        const Repeat & get_repeat() const { return repeat; }
+        Repeat & get_mutable_repeat() { return repeat; }
+        void set_repeat(const Repeat & value) { this->repeat = value; }
 
         /**
          * A list of views that should be concatenated and put into a column.
          */
-        const std::optional<std::vector<Spec>> & get_vconcat() const { return vconcat; }
-        std::optional<std::vector<Spec>> & get_mutable_vconcat() { return vconcat; }
-        void set_vconcat(const std::optional<std::vector<Spec>> & value) { this->vconcat = value; }
+        const std::vector<Spec> & get_vconcat() const { return vconcat; }
+        std::vector<Spec> & get_mutable_vconcat() { return vconcat; }
+        void set_vconcat(const std::vector<Spec> & value) { this->vconcat = value; }
 
         /**
          * A list of views that should be concatenated and put into a row.
          */
-        const std::optional<std::vector<Spec>> & get_hconcat() const { return hconcat; }
-        std::optional<std::vector<Spec>> & get_mutable_hconcat() { return hconcat; }
-        void set_hconcat(const std::optional<std::vector<Spec>> & value) { this->hconcat = value; }
+        const std::vector<Spec> & get_hconcat() const { return hconcat; }
+        std::vector<Spec> & get_mutable_hconcat() { return hconcat; }
+        void set_hconcat(const std::vector<Spec> & value) { this->hconcat = value; }
     };
 }
 
@@ -10507,7 +10507,7 @@ namespace quicktype {
     inline void from_json(const json & j, VgScheme& x) {
         x.set_count(get_stack_optional<double>(j, "count"));
         x.set_extent(get_stack_optional<std::vector<double>>(j, "extent"));
-        x.set_scheme(get_stack_optional<std::string>(j, "scheme"));
+        x.set_scheme(j.at("scheme").get<std::string>());
         x.set_step(get_stack_optional<double>(j, "step"));
     }
 
@@ -10634,7 +10634,7 @@ namespace quicktype {
     inline void from_json(const json & j, VgBinding& x) {
         x.set_element(get_stack_optional<std::string>(j, "element"));
         x.set_input(j.at("input").get<std::string>());
-        x.set_options(get_stack_optional<std::vector<std::string>>(j, "options"));
+        x.set_options(j.at("options").get<std::vector<std::string>>());
         x.set_max(get_stack_optional<double>(j, "max"));
         x.set_min(get_stack_optional<double>(j, "min"));
         x.set_step(get_stack_optional<double>(j, "step"));
@@ -11041,9 +11041,9 @@ namespace quicktype {
 
     inline void from_json(const json & j, Data& x) {
         x.set_format(get_stack_optional<DataFormat>(j, "format"));
-        x.set_url(get_stack_optional<std::string>(j, "url"));
-        x.set_values(get_stack_optional<std::variant<std::vector<ValuesValue>, std::map<std::string, nlohmann::json>, std::string>>(j, "values"));
-        x.set_name(get_stack_optional<std::string>(j, "name"));
+        x.set_url(j.at("url").get<std::string>());
+        x.set_values(j.at("values").get<Values>());
+        x.set_name(j.at("name").get<std::string>());
     }
 
     inline void to_json(json & j, const Data & x) {
@@ -11078,9 +11078,9 @@ namespace quicktype {
     }
 
     inline void from_json(const json & j, Selection& x) {
-        x.set_selection_not(get_heap_optional<std::variant<std::shared_ptr<Selection>, std::string>>(j, "not"));
-        x.set_selection_and(get_stack_optional<std::vector<SelectionOperand>>(j, "and"));
-        x.set_selection_or(get_stack_optional<std::vector<SelectionOperand>>(j, "or"));
+        x.set_selection_not(j.at("not").get<SelectionOperand>());
+        x.set_selection_and(j.at("and").get<std::vector<SelectionOperand>>());
+        x.set_selection_or(j.at("or").get<std::vector<SelectionOperand>>());
     }
 
     inline void to_json(json & j, const Selection & x) {
@@ -11118,15 +11118,15 @@ namespace quicktype {
     }
 
     inline void from_json(const json & j, Predicate& x) {
-        x.set_predicate_not(get_heap_optional<std::variant<std::shared_ptr<Predicate>, std::string>>(j, "not"));
-        x.set_predicate_and(get_stack_optional<std::vector<LogicalOperandPredicate>>(j, "and"));
-        x.set_predicate_or(get_stack_optional<std::vector<LogicalOperandPredicate>>(j, "or"));
-        x.set_equal(get_stack_optional<std::variant<bool, DateTime, double, std::string>>(j, "equal"));
-        x.set_field(get_stack_optional<std::string>(j, "field"));
+        x.set_predicate_not(j.at("not").get<LogicalOperandPredicate>());
+        x.set_predicate_and(j.at("and").get<std::vector<LogicalOperandPredicate>>());
+        x.set_predicate_or(j.at("or").get<std::vector<LogicalOperandPredicate>>());
+        x.set_equal(j.at("equal").get<Equal>());
+        x.set_field(j.at("field").get<std::string>());
         x.set_time_unit(get_stack_optional<TimeUnit>(j, "timeUnit"));
-        x.set_range(get_stack_optional<std::vector<RangeElement>>(j, "range"));
-        x.set_one_of(get_stack_optional<std::vector<Equal>>(j, "oneOf"));
-        x.set_selection(get_heap_optional<std::variant<std::shared_ptr<Selection>, std::string>>(j, "selection"));
+        x.set_range(j.at("range").get<std::vector<RangeElement>>());
+        x.set_one_of(j.at("oneOf").get<std::vector<Equal>>());
+        x.set_selection(j.at("selection").get<SelectionOperand>());
     }
 
     inline void to_json(json & j, const Predicate & x) {
@@ -11143,9 +11143,9 @@ namespace quicktype {
     }
 
     inline void from_json(const json & j, ConditionalValueDef& x) {
-        x.set_test(get_heap_optional<std::variant<std::shared_ptr<Predicate>, std::string>>(j, "test"));
+        x.set_test(j.at("test").get<LogicalOperandPredicate>());
         x.set_value(j.at("value").get<ConditionalValueDefValue>());
-        x.set_selection(get_heap_optional<std::variant<std::shared_ptr<Selection>, std::string>>(j, "selection"));
+        x.set_selection(j.at("selection").get<SelectionOperand>());
     }
 
     inline void to_json(json & j, const ConditionalValueDef & x) {
@@ -11288,9 +11288,9 @@ namespace quicktype {
     }
 
     inline void from_json(const json & j, ConditionalPredicateMarkPropFieldDefClass& x) {
-        x.set_test(get_heap_optional<std::variant<std::shared_ptr<Predicate>, std::string>>(j, "test"));
-        x.set_value(get_stack_optional<std::variant<bool, double, std::string>>(j, "value"));
-        x.set_selection(get_heap_optional<std::variant<std::shared_ptr<Selection>, std::string>>(j, "selection"));
+        x.set_test(j.at("test").get<LogicalOperandPredicate>());
+        x.set_value(j.at("value").get<ConditionalValueDefValue>());
+        x.set_selection(j.at("selection").get<SelectionOperand>());
         x.set_aggregate(get_stack_optional<AggregateOp>(j, "aggregate"));
         x.set_bin(get_stack_optional<std::variant<bool, BinParams>>(j, "bin"));
         x.set_field(get_stack_optional<std::variant<RepeatRef, std::string>>(j, "field"));
@@ -11298,7 +11298,7 @@ namespace quicktype {
         x.set_scale(get_stack_optional<Scale>(j, "scale"));
         x.set_sort(get_stack_optional<std::variant<SortField, SortEnum>>(j, "sort"));
         x.set_time_unit(get_stack_optional<TimeUnit>(j, "timeUnit"));
-        x.set_type(get_stack_optional<Type>(j, "type"));
+        x.set_type(j.at("type").get<Type>());
     }
 
     inline void to_json(json & j, const ConditionalPredicateMarkPropFieldDefClass & x) {
@@ -11325,7 +11325,7 @@ namespace quicktype {
         x.set_scale(get_stack_optional<Scale>(j, "scale"));
         x.set_sort(get_stack_optional<std::variant<SortField, SortEnum>>(j, "sort"));
         x.set_time_unit(get_stack_optional<TimeUnit>(j, "timeUnit"));
-        x.set_type(get_stack_optional<Type>(j, "type"));
+        x.set_type(j.at("type").get<Type>());
         x.set_value(get_stack_optional<std::variant<bool, double, std::string>>(j, "value"));
     }
 
@@ -11395,14 +11395,14 @@ namespace quicktype {
     }
 
     inline void from_json(const json & j, ConditionalPredicateFieldDefClass& x) {
-        x.set_test(get_heap_optional<std::variant<std::shared_ptr<Predicate>, std::string>>(j, "test"));
-        x.set_value(get_stack_optional<std::variant<bool, double, std::string>>(j, "value"));
-        x.set_selection(get_heap_optional<std::variant<std::shared_ptr<Selection>, std::string>>(j, "selection"));
+        x.set_test(j.at("test").get<LogicalOperandPredicate>());
+        x.set_value(j.at("value").get<ConditionalValueDefValue>());
+        x.set_selection(j.at("selection").get<SelectionOperand>());
         x.set_aggregate(get_stack_optional<AggregateOp>(j, "aggregate"));
         x.set_bin(get_stack_optional<std::variant<bool, BinParams>>(j, "bin"));
         x.set_field(get_stack_optional<std::variant<RepeatRef, std::string>>(j, "field"));
         x.set_time_unit(get_stack_optional<TimeUnit>(j, "timeUnit"));
-        x.set_type(get_stack_optional<Type>(j, "type"));
+        x.set_type(j.at("type").get<Type>());
     }
 
     inline void to_json(json & j, const ConditionalPredicateFieldDefClass & x) {
@@ -11423,7 +11423,7 @@ namespace quicktype {
         x.set_condition(get_stack_optional<std::variant<std::vector<ConditionalValueDef>, ConditionalPredicateFieldDefClass>>(j, "condition"));
         x.set_field(get_stack_optional<std::variant<RepeatRef, std::string>>(j, "field"));
         x.set_time_unit(get_stack_optional<TimeUnit>(j, "timeUnit"));
-        x.set_type(get_stack_optional<Type>(j, "type"));
+        x.set_type(j.at("type").get<Type>());
         x.set_value(get_stack_optional<std::variant<bool, double, std::string>>(j, "value"));
     }
 
@@ -11458,15 +11458,15 @@ namespace quicktype {
     }
 
     inline void from_json(const json & j, ConditionalPredicateTextFieldDefClass& x) {
-        x.set_test(get_heap_optional<std::variant<std::shared_ptr<Predicate>, std::string>>(j, "test"));
-        x.set_value(get_stack_optional<std::variant<bool, double, std::string>>(j, "value"));
-        x.set_selection(get_heap_optional<std::variant<std::shared_ptr<Selection>, std::string>>(j, "selection"));
+        x.set_test(j.at("test").get<LogicalOperandPredicate>());
+        x.set_value(j.at("value").get<ConditionalValueDefValue>());
+        x.set_selection(j.at("selection").get<SelectionOperand>());
         x.set_aggregate(get_stack_optional<AggregateOp>(j, "aggregate"));
         x.set_bin(get_stack_optional<std::variant<bool, BinParams>>(j, "bin"));
         x.set_field(get_stack_optional<std::variant<RepeatRef, std::string>>(j, "field"));
         x.set_format(get_stack_optional<std::string>(j, "format"));
         x.set_time_unit(get_stack_optional<TimeUnit>(j, "timeUnit"));
-        x.set_type(get_stack_optional<Type>(j, "type"));
+        x.set_type(j.at("type").get<Type>());
     }
 
     inline void to_json(json & j, const ConditionalPredicateTextFieldDefClass & x) {
@@ -11489,7 +11489,7 @@ namespace quicktype {
         x.set_field(get_stack_optional<std::variant<RepeatRef, std::string>>(j, "field"));
         x.set_format(get_stack_optional<std::string>(j, "format"));
         x.set_time_unit(get_stack_optional<TimeUnit>(j, "timeUnit"));
-        x.set_type(get_stack_optional<Type>(j, "type"));
+        x.set_type(j.at("type").get<Type>());
         x.set_value(get_stack_optional<std::variant<bool, double, std::string>>(j, "value"));
     }
 
@@ -11565,8 +11565,8 @@ namespace quicktype {
         x.set_sort(get_stack_optional<std::variant<SortField, SortEnum>>(j, "sort"));
         x.set_stack(get_stack_optional<StackOffset>(j, "stack"));
         x.set_time_unit(get_stack_optional<TimeUnit>(j, "timeUnit"));
-        x.set_type(get_stack_optional<Type>(j, "type"));
-        x.set_value(get_stack_optional<std::variant<bool, double, std::string>>(j, "value"));
+        x.set_type(j.at("type").get<Type>());
+        x.set_value(j.at("value").get<ConditionalValueDefValue>());
     }
 
     inline void to_json(json & j, const XClass & x) {
@@ -11588,8 +11588,8 @@ namespace quicktype {
         x.set_bin(get_stack_optional<std::variant<bool, BinParams>>(j, "bin"));
         x.set_field(get_stack_optional<std::variant<RepeatRef, std::string>>(j, "field"));
         x.set_time_unit(get_stack_optional<TimeUnit>(j, "timeUnit"));
-        x.set_type(get_stack_optional<Type>(j, "type"));
-        x.set_value(get_stack_optional<std::variant<bool, double, std::string>>(j, "value"));
+        x.set_type(j.at("type").get<Type>());
+        x.set_value(j.at("value").get<ConditionalValueDefValue>());
     }
 
     inline void to_json(json & j, const X2Class & x) {
@@ -11926,16 +11926,16 @@ namespace quicktype {
     }
 
     inline void from_json(const json & j, Transform& x) {
-        x.set_filter(get_heap_optional<std::variant<std::shared_ptr<Predicate>, std::string>>(j, "filter"));
+        x.set_filter(j.at("filter").get<LogicalOperandPredicate>());
         x.set_as(get_stack_optional<std::variant<std::vector<std::string>, std::string>>(j, "as"));
-        x.set_calculate(get_stack_optional<std::string>(j, "calculate"));
+        x.set_calculate(j.at("calculate").get<std::string>());
         x.set_transform_default(get_stack_optional<std::string>(j, "default"));
-        x.set_from(get_stack_optional<LookupData>(j, "from"));
-        x.set_lookup(get_stack_optional<std::string>(j, "lookup"));
-        x.set_bin(get_stack_optional<std::variant<bool, BinParams>>(j, "bin"));
-        x.set_field(get_stack_optional<std::string>(j, "field"));
-        x.set_time_unit(get_stack_optional<TimeUnit>(j, "timeUnit"));
-        x.set_aggregate(get_stack_optional<std::vector<AggregatedFieldDef>>(j, "aggregate"));
+        x.set_from(j.at("from").get<LookupData>());
+        x.set_lookup(j.at("lookup").get<std::string>());
+        x.set_bin(j.at("bin").get<Bin>());
+        x.set_field(j.at("field").get<std::string>());
+        x.set_time_unit(j.at("timeUnit").get<TimeUnit>());
+        x.set_aggregate(j.at("aggregate").get<std::vector<AggregatedFieldDef>>());
         x.set_groupby(get_stack_optional<std::vector<std::string>>(j, "groupby"));
     }
 
@@ -11958,14 +11958,14 @@ namespace quicktype {
         x.set_data(get_stack_optional<Data>(j, "data"));
         x.set_description(get_stack_optional<std::string>(j, "description"));
         x.set_height(get_stack_optional<double>(j, "height"));
-        x.set_layer(get_stack_optional<std::vector<LayerSpec>>(j, "layer"));
+        x.set_layer(j.at("layer").get<std::vector<LayerSpec>>());
         x.set_name(get_stack_optional<std::string>(j, "name"));
         x.set_resolve(get_stack_optional<Resolve>(j, "resolve"));
         x.set_title(get_stack_optional<std::variant<TitleParams, std::string>>(j, "title"));
         x.set_transform(get_stack_optional<std::vector<Transform>>(j, "transform"));
         x.set_width(get_stack_optional<double>(j, "width"));
-        x.set_encoding(get_stack_optional<Encoding>(j, "encoding"));
-        x.set_mark(get_stack_optional<std::variant<MarkDef, Mark>>(j, "mark"));
+        x.set_encoding(j.at("encoding").get<Encoding>());
+        x.set_mark(j.at("mark").get<AnyMark>());
         x.set_projection(get_stack_optional<Projection>(j, "projection"));
         x.set_selection(get_stack_optional<std::map<std::string, SelectionDef>>(j, "selection"));
     }
@@ -12002,21 +12002,21 @@ namespace quicktype {
         x.set_data(get_stack_optional<Data>(j, "data"));
         x.set_description(get_stack_optional<std::string>(j, "description"));
         x.set_height(get_stack_optional<double>(j, "height"));
-        x.set_layer(get_stack_optional<std::vector<LayerSpec>>(j, "layer"));
+        x.set_layer(j.at("layer").get<std::vector<LayerSpec>>());
         x.set_name(get_stack_optional<std::string>(j, "name"));
         x.set_resolve(get_stack_optional<Resolve>(j, "resolve"));
         x.set_title(get_stack_optional<std::variant<TitleParams, std::string>>(j, "title"));
         x.set_transform(get_stack_optional<std::vector<Transform>>(j, "transform"));
         x.set_width(get_stack_optional<double>(j, "width"));
-        x.set_encoding(get_stack_optional<Encoding>(j, "encoding"));
-        x.set_mark(get_stack_optional<std::variant<MarkDef, Mark>>(j, "mark"));
+        x.set_encoding(j.at("encoding").get<Encoding>());
+        x.set_mark(j.at("mark").get<AnyMark>());
         x.set_projection(get_stack_optional<Projection>(j, "projection"));
         x.set_selection(get_stack_optional<std::map<std::string, SelectionDef>>(j, "selection"));
-        x.set_facet(get_stack_optional<FacetMapping>(j, "facet"));
-        x.set_spec(get_heap_optional<Spec>(j, "spec"));
-        x.set_repeat(get_stack_optional<Repeat>(j, "repeat"));
-        x.set_vconcat(get_stack_optional<std::vector<Spec>>(j, "vconcat"));
-        x.set_hconcat(get_stack_optional<std::vector<Spec>>(j, "hconcat"));
+        x.set_facet(j.at("facet").get<FacetMapping>());
+        x.set_spec(j.at("spec").get<std::shared_ptr<Spec>>());
+        x.set_repeat(j.at("repeat").get<Repeat>());
+        x.set_vconcat(j.at("vconcat").get<std::vector<Spec>>());
+        x.set_hconcat(j.at("hconcat").get<std::vector<Spec>>());
     }
 
     inline void to_json(json & j, const Spec & x) {
@@ -12048,9 +12048,9 @@ namespace quicktype {
         x.set_config(get_stack_optional<Config>(j, "config"));
         x.set_data(get_stack_optional<Data>(j, "data"));
         x.set_description(get_stack_optional<std::string>(j, "description"));
-        x.set_encoding(get_stack_optional<EncodingWithFacet>(j, "encoding"));
+        x.set_encoding(j.at("encoding").get<EncodingWithFacet>());
         x.set_height(get_stack_optional<double>(j, "height"));
-        x.set_mark(get_stack_optional<std::variant<MarkDef, Mark>>(j, "mark"));
+        x.set_mark(j.at("mark").get<AnyMark>());
         x.set_name(get_stack_optional<std::string>(j, "name"));
         x.set_padding(get_stack_optional<std::variant<PaddingClass, double>>(j, "padding"));
         x.set_projection(get_stack_optional<Projection>(j, "projection"));
@@ -12058,13 +12058,13 @@ namespace quicktype {
         x.set_title(get_stack_optional<std::variant<TitleParams, std::string>>(j, "title"));
         x.set_transform(get_stack_optional<std::vector<Transform>>(j, "transform"));
         x.set_width(get_stack_optional<double>(j, "width"));
-        x.set_layer(get_stack_optional<std::vector<LayerSpec>>(j, "layer"));
+        x.set_layer(j.at("layer").get<std::vector<LayerSpec>>());
         x.set_resolve(get_stack_optional<Resolve>(j, "resolve"));
-        x.set_facet(get_stack_optional<FacetMapping>(j, "facet"));
-        x.set_spec(get_heap_optional<Spec>(j, "spec"));
-        x.set_repeat(get_stack_optional<Repeat>(j, "repeat"));
-        x.set_vconcat(get_stack_optional<std::vector<Spec>>(j, "vconcat"));
-        x.set_hconcat(get_stack_optional<std::vector<Spec>>(j, "hconcat"));
+        x.set_facet(j.at("facet").get<FacetMapping>());
+        x.set_spec(j.at("spec").get<std::shared_ptr<Spec>>());
+        x.set_repeat(j.at("repeat").get<Repeat>());
+        x.set_vconcat(j.at("vconcat").get<std::vector<Spec>>());
+        x.set_hconcat(j.at("hconcat").get<std::vector<Spec>>());
     }
 
     inline void to_json(json & j, const TopLevel & x) {
diff --git a/head/schema-csharp/test/inputs/schema/required-in-any-of.schema/default/QuickType.cs b/head/schema-csharp/test/inputs/schema/required-in-any-of.schema/default/QuickType.cs
new file mode 100644
index 0000000..88fef46
--- /dev/null
+++ b/head/schema-csharp/test/inputs/schema/required-in-any-of.schema/default/QuickType.cs
@@ -0,0 +1,70 @@
+// <auto-generated />
+//
+// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
+//
+//    using QuickType;
+//
+//    var topLevel = TopLevel.FromJson(jsonString);
+#nullable enable
+#pragma warning disable CS8618
+#pragma warning disable CS8601
+#pragma warning disable CS8602
+#pragma warning disable CS8603
+#pragma warning disable CS8604
+#pragma warning disable CS8625
+#pragma warning disable CS8765
+
+namespace QuickType
+{
+    using System;
+    using System.Collections.Generic;
+
+    using System.Globalization;
+    using Newtonsoft.Json;
+    using Newtonsoft.Json.Converters;
+
+    public partial class TopLevel
+    {
+        [JsonProperty("anyof", Required = Required.Always)]
+        public Anyof Anyof { get; set; }
+    }
+
+    public partial class Anyof
+    {
+        [JsonProperty("name", Required = Required.Always)]
+        public string Name { get; set; }
+
+        [JsonProperty("size", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
+        public string? Size { get; set; }
+    }
+
+    public partial class TopLevel
+    {
+        public static TopLevel FromJson(string json) => JsonConvert.DeserializeObject<TopLevel>(json, QuickType.Converter.Settings);
+    }
+
+    public static partial class Serialize
+    {
+        public static string ToJson(this TopLevel self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
+    }
+
+    internal static partial class Converter
+    {
+        public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
+        {
+            MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
+            DateParseHandling = DateParseHandling.None,
+            Converters =
+            {
+                new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
+            },
+        };
+    }
+}
+#pragma warning restore CS8618
+#pragma warning restore CS8601
+#pragma warning restore CS8602
+#pragma warning restore CS8603
+#pragma warning restore CS8604
+#pragma warning restore CS8625
+#pragma warning restore CS8765
diff --git a/base/schema-csharp/test/inputs/schema/vega-lite.schema/default/QuickType.cs b/head/schema-csharp/test/inputs/schema/vega-lite.schema/default/QuickType.cs
index 14be422..e95e1c2 100644
--- a/base/schema-csharp/test/inputs/schema/vega-lite.schema/default/QuickType.cs
+++ b/head/schema-csharp/test/inputs/schema/vega-lite.schema/default/QuickType.cs
@@ -76,8 +76,8 @@ namespace QuickType
         /// <summary>
         /// A key-value mapping between encoding channels and definition of fields.
         /// </summary>
-        [JsonProperty("encoding", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public EncodingWithFacet? Encoding { get; set; }
+        [JsonProperty("encoding", Required = Required.Always)]
+        public EncodingWithFacet Encoding { get; set; }
 
         /// <summary>
         /// The height of a visualization.
@@ -107,8 +107,8 @@ namespace QuickType
         /// * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
         /// object](mark.html#mark-def).
         /// </summary>
-        [JsonProperty("mark", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public AnyMark? Mark { get; set; }
+        [JsonProperty("mark", Required = Required.Always)]
+        public AnyMark Mark { get; set; }
 
         /// <summary>
         /// Name of the visualization for later reference.
@@ -185,8 +185,8 @@ namespace QuickType
         /// __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
         /// layering facet specifications is not allowed.
         /// </summary>
-        [JsonProperty("layer", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public LayerSpec[]? Layer { get; set; }
+        [JsonProperty("layer", Required = Required.Always)]
+        public LayerSpec[] Layer { get; set; }
 
         /// <summary>
         /// Scale, axis, and legend resolutions for layers.
@@ -206,33 +206,33 @@ namespace QuickType
         /// An object that describes mappings between `row` and `column` channels and their field
         /// definitions.
         /// </summary>
-        [JsonProperty("facet", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public FacetMapping? Facet { get; set; }
+        [JsonProperty("facet", Required = Required.Always)]
+        public FacetMapping Facet { get; set; }
 
         /// <summary>
         /// A specification of the view that gets faceted.
         /// </summary>
-        [JsonProperty("spec", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Spec? Spec { get; set; }
+        [JsonProperty("spec", Required = Required.Always)]
+        public Spec Spec { get; set; }
 
         /// <summary>
         /// An object that describes what fields should be repeated into views that are laid out as a
         /// `row` or `column`.
         /// </summary>
-        [JsonProperty("repeat", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Repeat? Repeat { get; set; }
+        [JsonProperty("repeat", Required = Required.Always)]
+        public Repeat Repeat { get; set; }
 
         /// <summary>
         /// A list of views that should be concatenated and put into a column.
         /// </summary>
-        [JsonProperty("vconcat", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Spec[]? Vconcat { get; set; }
+        [JsonProperty("vconcat", Required = Required.Always)]
+        public Spec[] Vconcat { get; set; }
 
         /// <summary>
         /// A list of views that should be concatenated and put into a row.
         /// </summary>
-        [JsonProperty("hconcat", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Spec[]? Hconcat { get; set; }
+        [JsonProperty("hconcat", Required = Required.Always)]
+        public Spec[] Hconcat { get; set; }
     }
 
     public partial class AutoSizeParams
@@ -2061,8 +2061,8 @@ namespace QuickType
         [JsonProperty("extent", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
         public double[]? Extent { get; set; }
 
-        [JsonProperty("scheme", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public string? Scheme { get; set; }
+        [JsonProperty("scheme", Required = Required.Always)]
+        public string Scheme { get; set; }
 
         [JsonProperty("step", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
         public double? Step { get; set; }
@@ -2587,8 +2587,8 @@ namespace QuickType
         [JsonProperty("input", Required = Required.Always)]
         public string Input { get; set; }
 
-        [JsonProperty("options", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public string[]? Options { get; set; }
+        [JsonProperty("options", Required = Required.Always)]
+        public string[] Options { get; set; }
 
         [JsonProperty("max", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
         public double? Max { get; set; }
@@ -3564,8 +3564,8 @@ namespace QuickType
         /// An URL from which to load the data set. Use the `format.type` property
         /// to ensure the loaded data is correctly parsed.
         /// </summary>
-        [JsonProperty("url", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public string? Url { get; set; }
+        [JsonProperty("url", Required = Required.Always)]
+        public string Url { get; set; }
 
         /// <summary>
         /// The full data set, included inline. This can be an array of objects or primitive values
@@ -3573,14 +3573,14 @@ namespace QuickType
         /// Arrays of primitive values are ingested as objects with a `data` property. Strings are
         /// parsed according to the specified format type.
         /// </summary>
-        [JsonProperty("values", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Values? Values { get; set; }
+        [JsonProperty("values", Required = Required.Always)]
+        public Values Values { get; set; }
 
         /// <summary>
         /// Provide a placeholder name and bind data at runtime.
         /// </summary>
-        [JsonProperty("name", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public string? Name { get; set; }
+        [JsonProperty("name", Required = Required.Always)]
+        public string Name { get; set; }
     }
 
     /// <summary>
@@ -3910,8 +3910,8 @@ namespace QuickType
         /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
         /// [geographic projection](projection.html) is applied.
         /// </summary>
-        [JsonProperty("type", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalPredicateValueDefType? Type { get; set; }
+        [JsonProperty("type", Required = Required.Always)]
+        public ConditionalPredicateValueDefType Type { get; set; }
 
         /// <summary>
         /// A constant value in visual domain.
@@ -3990,8 +3990,8 @@ namespace QuickType
 
     public partial class ConditionalValueDef
     {
-        [JsonProperty("test", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public LogicalOperandPredicate? Test { get; set; }
+        [JsonProperty("test", Required = Required.Always)]
+        public LogicalOperandPredicate Test { get; set; }
 
         /// <summary>
         /// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
@@ -4004,46 +4004,46 @@ namespace QuickType
         /// A [selection name](selection.html), or a series of [composed
         /// selections](selection.html#compose).
         /// </summary>
-        [JsonProperty("selection", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public SelectionOperand? Selection { get; set; }
+        [JsonProperty("selection", Required = Required.Always)]
+        public SelectionOperand Selection { get; set; }
     }
 
     public partial class Selection
     {
-        [JsonProperty("not", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public SelectionOperand? Not { get; set; }
+        [JsonProperty("not", Required = Required.Always)]
+        public SelectionOperand Not { get; set; }
 
-        [JsonProperty("and", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public SelectionOperand[]? And { get; set; }
+        [JsonProperty("and", Required = Required.Always)]
+        public SelectionOperand[] And { get; set; }
 
-        [JsonProperty("or", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public SelectionOperand[]? Or { get; set; }
+        [JsonProperty("or", Required = Required.Always)]
+        public SelectionOperand[] Or { get; set; }
     }
 
     public partial class Predicate
     {
-        [JsonProperty("not", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public LogicalOperandPredicate? Not { get; set; }
+        [JsonProperty("not", Required = Required.Always)]
+        public LogicalOperandPredicate Not { get; set; }
 
-        [JsonProperty("and", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public LogicalOperandPredicate[]? And { get; set; }
+        [JsonProperty("and", Required = Required.Always)]
+        public LogicalOperandPredicate[] And { get; set; }
 
-        [JsonProperty("or", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public LogicalOperandPredicate[]? Or { get; set; }
+        [JsonProperty("or", Required = Required.Always)]
+        public LogicalOperandPredicate[] Or { get; set; }
 
         /// <summary>
         /// The value that the field should be equal to.
         /// </summary>
-        [JsonProperty("equal", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Equal? Equal { get; set; }
+        [JsonProperty("equal", Required = Required.Always)]
+        public Equal Equal { get; set; }
 
         /// <summary>
         /// Field to be filtered.
         ///
         /// Field to be filtered
         /// </summary>
-        [JsonProperty("field", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public string? Field { get; set; }
+        [JsonProperty("field", Required = Required.Always)]
+        public string Field { get; set; }
 
         /// <summary>
         /// Time unit for the field to be filtered.
@@ -4057,21 +4057,21 @@ namespace QuickType
         /// An array of inclusive minimum and maximum values
         /// for a field value of a data item to be included in the filtered data.
         /// </summary>
-        [JsonProperty("range", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public RangeElement[]? Range { get; set; }
+        [JsonProperty("range", Required = Required.Always)]
+        public RangeElement[] Range { get; set; }
 
         /// <summary>
         /// A set of values that the `field`'s value should be a member of,
         /// for a data item included in the filtered data.
         /// </summary>
-        [JsonProperty("oneOf", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Equal[]? OneOf { get; set; }
+        [JsonProperty("oneOf", Required = Required.Always)]
+        public Equal[] OneOf { get; set; }
 
         /// <summary>
         /// Filter using a selection name.
         /// </summary>
-        [JsonProperty("selection", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public SelectionOperand? Selection { get; set; }
+        [JsonProperty("selection", Required = Required.Always)]
+        public SelectionOperand Selection { get; set; }
     }
 
     /// <summary>
@@ -4158,22 +4158,22 @@ namespace QuickType
 
     public partial class ConditionalPredicateMarkPropFieldDefClass
     {
-        [JsonProperty("test", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public LogicalOperandPredicate? Test { get; set; }
+        [JsonProperty("test", Required = Required.Always)]
+        public LogicalOperandPredicate Test { get; set; }
 
         /// <summary>
         /// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
         /// `0` to `1` for opacity).
         /// </summary>
-        [JsonProperty("value", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalValueDefValue? Value { get; set; }
+        [JsonProperty("value", Required = Required.Always)]
+        public ConditionalValueDefValue Value { get; set; }
 
         /// <summary>
         /// A [selection name](selection.html), or a series of [composed
         /// selections](selection.html#compose).
         /// </summary>
-        [JsonProperty("selection", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public SelectionOperand? Selection { get; set; }
+        [JsonProperty("selection", Required = Required.Always)]
+        public SelectionOperand Selection { get; set; }
 
         /// <summary>
         /// Aggregation function for the field
@@ -4254,8 +4254,8 @@ namespace QuickType
         /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
         /// [geographic projection](projection.html) is applied.
         /// </summary>
-        [JsonProperty("type", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalPredicateValueDefType? Type { get; set; }
+        [JsonProperty("type", Required = Required.Always)]
+        public ConditionalPredicateValueDefType Type { get; set; }
     }
 
     /// <summary>
@@ -4960,8 +4960,8 @@ namespace QuickType
         /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
         /// [geographic projection](projection.html) is applied.
         /// </summary>
-        [JsonProperty("type", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalPredicateValueDefType? Type { get; set; }
+        [JsonProperty("type", Required = Required.Always)]
+        public ConditionalPredicateValueDefType Type { get; set; }
 
         /// <summary>
         /// A constant value in visual domain.
@@ -4972,22 +4972,22 @@ namespace QuickType
 
     public partial class ConditionalPredicateFieldDefClass
     {
-        [JsonProperty("test", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public LogicalOperandPredicate? Test { get; set; }
+        [JsonProperty("test", Required = Required.Always)]
+        public LogicalOperandPredicate Test { get; set; }
 
         /// <summary>
         /// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
         /// `0` to `1` for opacity).
         /// </summary>
-        [JsonProperty("value", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalValueDefValue? Value { get; set; }
+        [JsonProperty("value", Required = Required.Always)]
+        public ConditionalValueDefValue Value { get; set; }
 
         /// <summary>
         /// A [selection name](selection.html), or a series of [composed
         /// selections](selection.html#compose).
         /// </summary>
-        [JsonProperty("selection", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public SelectionOperand? Selection { get; set; }
+        [JsonProperty("selection", Required = Required.Always)]
+        public SelectionOperand Selection { get; set; }
 
         /// <summary>
         /// Aggregation function for the field
@@ -5038,8 +5038,8 @@ namespace QuickType
         /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
         /// [geographic projection](projection.html) is applied.
         /// </summary>
-        [JsonProperty("type", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalPredicateValueDefType? Type { get; set; }
+        [JsonProperty("type", Required = Required.Always)]
+        public ConditionalPredicateValueDefType Type { get; set; }
     }
 
     public partial class OrderFieldDef
@@ -5191,8 +5191,8 @@ namespace QuickType
         /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
         /// [geographic projection](projection.html) is applied.
         /// </summary>
-        [JsonProperty("type", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalPredicateValueDefType? Type { get; set; }
+        [JsonProperty("type", Required = Required.Always)]
+        public ConditionalPredicateValueDefType Type { get; set; }
 
         /// <summary>
         /// A constant value in visual domain.
@@ -5203,22 +5203,22 @@ namespace QuickType
 
     public partial class ConditionalPredicateTextFieldDefClass
     {
-        [JsonProperty("test", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public LogicalOperandPredicate? Test { get; set; }
+        [JsonProperty("test", Required = Required.Always)]
+        public LogicalOperandPredicate Test { get; set; }
 
         /// <summary>
         /// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
         /// `0` to `1` for opacity).
         /// </summary>
-        [JsonProperty("value", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalValueDefValue? Value { get; set; }
+        [JsonProperty("value", Required = Required.Always)]
+        public ConditionalValueDefValue Value { get; set; }
 
         /// <summary>
         /// A [selection name](selection.html), or a series of [composed
         /// selections](selection.html#compose).
         /// </summary>
-        [JsonProperty("selection", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public SelectionOperand? Selection { get; set; }
+        [JsonProperty("selection", Required = Required.Always)]
+        public SelectionOperand Selection { get; set; }
 
         /// <summary>
         /// Aggregation function for the field
@@ -5276,8 +5276,8 @@ namespace QuickType
         /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
         /// [geographic projection](projection.html) is applied.
         /// </summary>
-        [JsonProperty("type", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalPredicateValueDefType? Type { get; set; }
+        [JsonProperty("type", Required = Required.Always)]
+        public ConditionalPredicateValueDefType Type { get; set; }
     }
 
     /// <summary>
@@ -5393,15 +5393,15 @@ namespace QuickType
         /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
         /// [geographic projection](projection.html) is applied.
         /// </summary>
-        [JsonProperty("type", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalPredicateValueDefType? Type { get; set; }
+        [JsonProperty("type", Required = Required.Always)]
+        public ConditionalPredicateValueDefType Type { get; set; }
 
         /// <summary>
         /// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
         /// `0` to `1` for opacity).
         /// </summary>
-        [JsonProperty("value", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalValueDefValue? Value { get; set; }
+        [JsonProperty("value", Required = Required.Always)]
+        public ConditionalValueDefValue Value { get; set; }
     }
 
     public partial class Axis
@@ -5678,15 +5678,15 @@ namespace QuickType
         /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
         /// [geographic projection](projection.html) is applied.
         /// </summary>
-        [JsonProperty("type", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalPredicateValueDefType? Type { get; set; }
+        [JsonProperty("type", Required = Required.Always)]
+        public ConditionalPredicateValueDefType Type { get; set; }
 
         /// <summary>
         /// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
         /// `0` to `1` for opacity).
         /// </summary>
-        [JsonProperty("value", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalValueDefValue? Value { get; set; }
+        [JsonProperty("value", Required = Required.Always)]
+        public ConditionalValueDefValue Value { get; set; }
     }
 
     /// <summary>
@@ -5753,8 +5753,8 @@ namespace QuickType
         /// __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
         /// layering facet specifications is not allowed.
         /// </summary>
-        [JsonProperty("layer", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public LayerSpec[]? Layer { get; set; }
+        [JsonProperty("layer", Required = Required.Always)]
+        public LayerSpec[] Layer { get; set; }
 
         /// <summary>
         /// Name of the visualization for later reference.
@@ -5816,8 +5816,8 @@ namespace QuickType
         /// <summary>
         /// A key-value mapping between encoding channels and definition of fields.
         /// </summary>
-        [JsonProperty("encoding", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Encoding? Encoding { get; set; }
+        [JsonProperty("encoding", Required = Required.Always)]
+        public Encoding Encoding { get; set; }
 
         /// <summary>
         /// A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
@@ -5825,8 +5825,8 @@ namespace QuickType
         /// * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
         /// object](mark.html#mark-def).
         /// </summary>
-        [JsonProperty("mark", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public AnyMark? Mark { get; set; }
+        [JsonProperty("mark", Required = Required.Always)]
+        public AnyMark Mark { get; set; }
 
         /// <summary>
         /// An object defining properties of geographic projection.
@@ -5847,33 +5847,33 @@ namespace QuickType
         /// An object that describes mappings between `row` and `column` channels and their field
         /// definitions.
         /// </summary>
-        [JsonProperty("facet", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public FacetMapping? Facet { get; set; }
+        [JsonProperty("facet", Required = Required.Always)]
+        public FacetMapping Facet { get; set; }
 
         /// <summary>
         /// A specification of the view that gets faceted.
         /// </summary>
-        [JsonProperty("spec", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Spec? SpecSpec { get; set; }
+        [JsonProperty("spec", Required = Required.Always)]
+        public Spec SpecSpec { get; set; }
 
         /// <summary>
         /// An object that describes what fields should be repeated into views that are laid out as a
         /// `row` or `column`.
         /// </summary>
-        [JsonProperty("repeat", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Repeat? Repeat { get; set; }
+        [JsonProperty("repeat", Required = Required.Always)]
+        public Repeat Repeat { get; set; }
 
         /// <summary>
         /// A list of views that should be concatenated and put into a column.
         /// </summary>
-        [JsonProperty("vconcat", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Spec[]? Vconcat { get; set; }
+        [JsonProperty("vconcat", Required = Required.Always)]
+        public Spec[] Vconcat { get; set; }
 
         /// <summary>
         /// A list of views that should be concatenated and put into a row.
         /// </summary>
-        [JsonProperty("hconcat", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Spec[]? Hconcat { get; set; }
+        [JsonProperty("hconcat", Required = Required.Always)]
+        public Spec[] Hconcat { get; set; }
     }
 
     /// <summary>
@@ -6031,8 +6031,8 @@ namespace QuickType
         /// __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
         /// layering facet specifications is not allowed.
         /// </summary>
-        [JsonProperty("layer", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public LayerSpec[]? Layer { get; set; }
+        [JsonProperty("layer", Required = Required.Always)]
+        public LayerSpec[] Layer { get; set; }
 
         /// <summary>
         /// Name of the visualization for later reference.
@@ -6086,8 +6086,8 @@ namespace QuickType
         /// <summary>
         /// A key-value mapping between encoding channels and definition of fields.
         /// </summary>
-        [JsonProperty("encoding", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Encoding? Encoding { get; set; }
+        [JsonProperty("encoding", Required = Required.Always)]
+        public Encoding Encoding { get; set; }
 
         /// <summary>
         /// A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
@@ -6095,8 +6095,8 @@ namespace QuickType
         /// * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
         /// object](mark.html#mark-def).
         /// </summary>
-        [JsonProperty("mark", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public AnyMark? Mark { get; set; }
+        [JsonProperty("mark", Required = Required.Always)]
+        public AnyMark Mark { get; set; }
 
         /// <summary>
         /// An object defining properties of geographic projection.
@@ -6737,8 +6737,8 @@ namespace QuickType
         /// (3) a [selection predicate](filter.html#selection-predicate);
         /// or (4) a logical operand that combines (1), (2), or (3).
         /// </summary>
-        [JsonProperty("filter", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public LogicalOperandPredicate? Filter { get; set; }
+        [JsonProperty("filter", Required = Required.Always)]
+        public LogicalOperandPredicate Filter { get; set; }
 
         /// <summary>
         /// The field for storing the computed formula value.
@@ -6759,8 +6759,8 @@ namespace QuickType
         /// A [expression](types.html#expression) string. Use the variable `datum` to refer to the
         /// current data object.
         /// </summary>
-        [JsonProperty("calculate", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public string? Calculate { get; set; }
+        [JsonProperty("calculate", Required = Required.Always)]
+        public string Calculate { get; set; }
 
         /// <summary>
         /// The default value to use if lookup fails.
@@ -6773,40 +6773,40 @@ namespace QuickType
         /// <summary>
         /// Secondary data reference.
         /// </summary>
-        [JsonProperty("from", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public LookupData? From { get; set; }
+        [JsonProperty("from", Required = Required.Always)]
+        public LookupData From { get; set; }
 
         /// <summary>
         /// Key in primary data source.
         /// </summary>
-        [JsonProperty("lookup", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public string? Lookup { get; set; }
+        [JsonProperty("lookup", Required = Required.Always)]
+        public string Lookup { get; set; }
 
         /// <summary>
         /// An object indicating bin properties, or simply `true` for using default bin parameters.
         /// </summary>
-        [JsonProperty("bin", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Bin? Bin { get; set; }
+        [JsonProperty("bin", Required = Required.Always)]
+        public Bin Bin { get; set; }
 
         /// <summary>
         /// The data field to bin.
         ///
         /// The data field to apply time unit.
         /// </summary>
-        [JsonProperty("field", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public string? Field { get; set; }
+        [JsonProperty("field", Required = Required.Always)]
+        public string Field { get; set; }
 
         /// <summary>
         /// The timeUnit.
         /// </summary>
-        [JsonProperty("timeUnit", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public TimeUnit? TimeUnit { get; set; }
+        [JsonProperty("timeUnit", Required = Required.Always)]
+        public TimeUnit TimeUnit { get; set; }
 
         /// <summary>
         /// Array of objects that define fields to aggregate.
         /// </summary>
-        [JsonProperty("aggregate", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public AggregatedFieldDef[]? Aggregate { get; set; }
+        [JsonProperty("aggregate", Required = Required.Always)]
+        public AggregatedFieldDef[] Aggregate { get; set; }
 
         /// <summary>
         /// The data fields to group by. If not specified, a single group containing all data objects
diff --git a/head/schema-csharp-SystemTextJson/test/inputs/schema/required-in-any-of.schema/default/QuickType.cs b/head/schema-csharp-SystemTextJson/test/inputs/schema/required-in-any-of.schema/default/QuickType.cs
new file mode 100644
index 0000000..8bef9ad
--- /dev/null
+++ b/head/schema-csharp-SystemTextJson/test/inputs/schema/required-in-any-of.schema/default/QuickType.cs
@@ -0,0 +1,177 @@
+// <auto-generated />
+//
+// To parse this JSON data, add NuGet 'System.Text.Json' then do:
+//
+//    using QuickType;
+//
+//    var topLevel = TopLevel.FromJson(jsonString);
+#nullable enable
+#pragma warning disable CS8618
+#pragma warning disable CS8601
+#pragma warning disable CS8602
+#pragma warning disable CS8603
+
+namespace QuickType
+{
+    using System;
+    using System.Collections.Generic;
+
+    using System.Text.Json;
+    using System.Text.Json.Serialization;
+    using System.Globalization;
+
+    public partial class TopLevel
+    {
+        [JsonRequired]
+        [JsonPropertyName("anyof")]
+        public Anyof Anyof { get; set; }
+    }
+
+    public partial class Anyof
+    {
+        [JsonRequired]
+        [JsonPropertyName("name")]
+        public string Name { get; set; }
+
+        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonPropertyName("size")]
+        public string? Size { get; set; }
+    }
+
+    public partial class TopLevel
+    {
+        public static TopLevel FromJson(string json) => JsonSerializer.Deserialize<TopLevel>(json, QuickType.Converter.Settings);
+    }
+
+    public static partial class Serialize
+    {
+        public static string ToJson(this TopLevel self) => JsonSerializer.Serialize(self, QuickType.Converter.Settings);
+    }
+
+    internal static partial class Converter
+    {
+        public static readonly JsonSerializerOptions Settings = new(JsonSerializerDefaults.General)
+        {
+            Converters =
+            {
+                new DateOnlyConverter(),
+                new TimeOnlyConverter(),
+                IsoDateTimeOffsetConverter.Singleton
+            },
+        };
+    }
+    
+    public class DateOnlyConverter : JsonConverter<DateOnly>
+    {
+        private readonly string serializationFormat;
+        public DateOnlyConverter() : this(null) { }
+
+        public DateOnlyConverter(string? serializationFormat)
+        {
+                this.serializationFormat = serializationFormat ?? "yyyy-MM-dd";
+        }
+
+        public override DateOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+        {
+                var value = reader.GetString();
+                return DateOnly.Parse(value!);
+        }
+
+        public override void Write(Utf8JsonWriter writer, DateOnly value, JsonSerializerOptions options)
+                => writer.WriteStringValue(value.ToString(serializationFormat));
+    }
+
+    public class TimeOnlyConverter : JsonConverter<TimeOnly>
+    {
+        private readonly string serializationFormat;
+
+        public TimeOnlyConverter() : this(null) { }
+
+        public TimeOnlyConverter(string? serializationFormat)
+        {
+                this.serializationFormat = serializationFormat ?? "HH:mm:ss.fff";
+        }
+
+        public override TimeOnly Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+        {
+                var value = reader.GetString();
+                return TimeOnly.Parse(value!);
+        }
+
+        public override void Write(Utf8JsonWriter writer, TimeOnly value, JsonSerializerOptions options)
+                => writer.WriteStringValue(value.ToString(serializationFormat));
+    }
+
+    internal class IsoDateTimeOffsetConverter : JsonConverter<DateTimeOffset>
+    {
+        public override bool CanConvert(Type t) => t == typeof(DateTimeOffset);
+
+        private const string DefaultDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";
+
+        private DateTimeStyles _dateTimeStyles = DateTimeStyles.RoundtripKind;
+        private string? _dateTimeFormat;
+        private CultureInfo? _culture;
+
+        public DateTimeStyles DateTimeStyles
+        {
+                get => _dateTimeStyles;
+                set => _dateTimeStyles = value;
+        }
+
+        public string? DateTimeFormat
+        {
+                get => _dateTimeFormat ?? string.Empty;
+                set => _dateTimeFormat = (string.IsNullOrEmpty(value)) ? null : value;
+        }
+
+        public CultureInfo Culture
+        {
+                get => _culture ?? CultureInfo.CurrentCulture;
+                set => _culture = value;
+        }
+
+        public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options)
+        {
+                string text;
+
+
+                if ((_dateTimeStyles & DateTimeStyles.AdjustToUniversal) == DateTimeStyles.AdjustToUniversal
+                        || (_dateTimeStyles & DateTimeStyles.AssumeUniversal) == DateTimeStyles.AssumeUniversal)
+                {
+                        value = value.ToUniversalTime();
+                }
+
+                text = value.ToString(_dateTimeFormat ?? DefaultDateTimeFormat, Culture);
+
+                writer.WriteStringValue(text);
+        }
+
+        public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+        {
+                string? dateText = reader.GetString();
+
+                if (string.IsNullOrEmpty(dateText) == false)
+                {
+                        if (!string.IsNullOrEmpty(_dateTimeFormat))
+                        {
+                                return DateTimeOffset.ParseExact(dateText, _dateTimeFormat, Culture, _dateTimeStyles);
+                        }
+                        else
+                        {
+                                return DateTimeOffset.Parse(dateText, Culture, _dateTimeStyles);
+                        }
+                }
+                else
+                {
+                        return default(DateTimeOffset);
+                }
+        }
+
+
+        public static readonly IsoDateTimeOffsetConverter Singleton = new IsoDateTimeOffsetConverter();
+    }
+}
+#pragma warning restore CS8618
+#pragma warning restore CS8601
+#pragma warning restore CS8602
+#pragma warning restore CS8603
diff --git a/base/schema-csharp-SystemTextJson/test/inputs/schema/vega-lite.schema/default/QuickType.cs b/head/schema-csharp-SystemTextJson/test/inputs/schema/vega-lite.schema/default/QuickType.cs
index 2179c69..5965574 100644
--- a/base/schema-csharp-SystemTextJson/test/inputs/schema/vega-lite.schema/default/QuickType.cs
+++ b/head/schema-csharp-SystemTextJson/test/inputs/schema/vega-lite.schema/default/QuickType.cs
@@ -79,9 +79,9 @@ namespace QuickType
         /// <summary>
         /// A key-value mapping between encoding channels and definition of fields.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("encoding")]
-        public EncodingWithFacet? Encoding { get; set; }
+        public EncodingWithFacet Encoding { get; set; }
 
         /// <summary>
         /// The height of a visualization.
@@ -112,9 +112,9 @@ namespace QuickType
         /// * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
         /// object](mark.html#mark-def).
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("mark")]
-        public AnyMark? Mark { get; set; }
+        public AnyMark Mark { get; set; }
 
         /// <summary>
         /// Name of the visualization for later reference.
@@ -198,9 +198,9 @@ namespace QuickType
         /// __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
         /// layering facet specifications is not allowed.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("layer")]
-        public LayerSpec[]? Layer { get; set; }
+        public LayerSpec[] Layer { get; set; }
 
         /// <summary>
         /// Scale, axis, and legend resolutions for layers.
@@ -221,38 +221,38 @@ namespace QuickType
         /// An object that describes mappings between `row` and `column` channels and their field
         /// definitions.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("facet")]
-        public FacetMapping? Facet { get; set; }
+        public FacetMapping Facet { get; set; }
 
         /// <summary>
         /// A specification of the view that gets faceted.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("spec")]
-        public Spec? Spec { get; set; }
+        public Spec Spec { get; set; }
 
         /// <summary>
         /// An object that describes what fields should be repeated into views that are laid out as a
         /// `row` or `column`.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("repeat")]
-        public Repeat? Repeat { get; set; }
+        public Repeat Repeat { get; set; }
 
         /// <summary>
         /// A list of views that should be concatenated and put into a column.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("vconcat")]
-        public Spec[]? Vconcat { get; set; }
+        public Spec[] Vconcat { get; set; }
 
         /// <summary>
         /// A list of views that should be concatenated and put into a row.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("hconcat")]
-        public Spec[]? Hconcat { get; set; }
+        public Spec[] Hconcat { get; set; }
     }
 
     public partial class AutoSizeParams
@@ -2318,9 +2318,9 @@ namespace QuickType
         [JsonPropertyName("extent")]
         public double[]? Extent { get; set; }
 
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("scheme")]
-        public string? Scheme { get; set; }
+        public string Scheme { get; set; }
 
         [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
         [JsonPropertyName("step")]
@@ -2896,9 +2896,9 @@ namespace QuickType
         [JsonPropertyName("input")]
         public string Input { get; set; }
 
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("options")]
-        public string[]? Options { get; set; }
+        public string[] Options { get; set; }
 
         [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
         [JsonPropertyName("max")]
@@ -3989,9 +3989,9 @@ namespace QuickType
         /// An URL from which to load the data set. Use the `format.type` property
         /// to ensure the loaded data is correctly parsed.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("url")]
-        public string? Url { get; set; }
+        public string Url { get; set; }
 
         /// <summary>
         /// The full data set, included inline. This can be an array of objects or primitive values
@@ -3999,16 +3999,16 @@ namespace QuickType
         /// Arrays of primitive values are ingested as objects with a `data` property. Strings are
         /// parsed according to the specified format type.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("values")]
-        public Values? Values { get; set; }
+        public Values Values { get; set; }
 
         /// <summary>
         /// Provide a placeholder name and bind data at runtime.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("name")]
-        public string? Name { get; set; }
+        public string Name { get; set; }
     }
 
     /// <summary>
@@ -4364,9 +4364,9 @@ namespace QuickType
         /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
         /// [geographic projection](projection.html) is applied.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("type")]
-        public ConditionalPredicateValueDefType? Type { get; set; }
+        public ConditionalPredicateValueDefType Type { get; set; }
 
         /// <summary>
         /// A constant value in visual domain.
@@ -4454,9 +4454,9 @@ namespace QuickType
 
     public partial class ConditionalValueDef
     {
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("test")]
-        public LogicalOperandPredicate? Test { get; set; }
+        public LogicalOperandPredicate Test { get; set; }
 
         /// <summary>
         /// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
@@ -4470,55 +4470,55 @@ namespace QuickType
         /// A [selection name](selection.html), or a series of [composed
         /// selections](selection.html#compose).
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("selection")]
-        public SelectionOperand? Selection { get; set; }
+        public SelectionOperand Selection { get; set; }
     }
 
     public partial class Selection
     {
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("not")]
-        public SelectionOperand? Not { get; set; }
+        public SelectionOperand Not { get; set; }
 
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("and")]
-        public SelectionOperand[]? And { get; set; }
+        public SelectionOperand[] And { get; set; }
 
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("or")]
-        public SelectionOperand[]? Or { get; set; }
+        public SelectionOperand[] Or { get; set; }
     }
 
     public partial class Predicate
     {
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("not")]
-        public LogicalOperandPredicate? Not { get; set; }
+        public LogicalOperandPredicate Not { get; set; }
 
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("and")]
-        public LogicalOperandPredicate[]? And { get; set; }
+        public LogicalOperandPredicate[] And { get; set; }
 
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("or")]
-        public LogicalOperandPredicate[]? Or { get; set; }
+        public LogicalOperandPredicate[] Or { get; set; }
 
         /// <summary>
         /// The value that the field should be equal to.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("equal")]
-        public Equal? Equal { get; set; }
+        public Equal Equal { get; set; }
 
         /// <summary>
         /// Field to be filtered.
         ///
         /// Field to be filtered
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("field")]
-        public string? Field { get; set; }
+        public string Field { get; set; }
 
         /// <summary>
         /// Time unit for the field to be filtered.
@@ -4533,24 +4533,24 @@ namespace QuickType
         /// An array of inclusive minimum and maximum values
         /// for a field value of a data item to be included in the filtered data.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("range")]
-        public RangeElement[]? Range { get; set; }
+        public RangeElement[] Range { get; set; }
 
         /// <summary>
         /// A set of values that the `field`'s value should be a member of,
         /// for a data item included in the filtered data.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("oneOf")]
-        public Equal[]? OneOf { get; set; }
+        public Equal[] OneOf { get; set; }
 
         /// <summary>
         /// Filter using a selection name.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("selection")]
-        public SelectionOperand? Selection { get; set; }
+        public SelectionOperand Selection { get; set; }
     }
 
     /// <summary>
@@ -4647,25 +4647,25 @@ namespace QuickType
 
     public partial class ConditionalPredicateMarkPropFieldDefClass
     {
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("test")]
-        public LogicalOperandPredicate? Test { get; set; }
+        public LogicalOperandPredicate Test { get; set; }
 
         /// <summary>
         /// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
         /// `0` to `1` for opacity).
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("value")]
-        public ConditionalValueDefValue? Value { get; set; }
+        public ConditionalValueDefValue Value { get; set; }
 
         /// <summary>
         /// A [selection name](selection.html), or a series of [composed
         /// selections](selection.html#compose).
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("selection")]
-        public SelectionOperand? Selection { get; set; }
+        public SelectionOperand Selection { get; set; }
 
         /// <summary>
         /// Aggregation function for the field
@@ -4751,9 +4751,9 @@ namespace QuickType
         /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
         /// [geographic projection](projection.html) is applied.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("type")]
-        public ConditionalPredicateValueDefType? Type { get; set; }
+        public ConditionalPredicateValueDefType Type { get; set; }
     }
 
     /// <summary>
@@ -5511,9 +5511,9 @@ namespace QuickType
         /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
         /// [geographic projection](projection.html) is applied.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("type")]
-        public ConditionalPredicateValueDefType? Type { get; set; }
+        public ConditionalPredicateValueDefType Type { get; set; }
 
         /// <summary>
         /// A constant value in visual domain.
@@ -5525,25 +5525,25 @@ namespace QuickType
 
     public partial class ConditionalPredicateFieldDefClass
     {
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("test")]
-        public LogicalOperandPredicate? Test { get; set; }
+        public LogicalOperandPredicate Test { get; set; }
 
         /// <summary>
         /// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
         /// `0` to `1` for opacity).
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("value")]
-        public ConditionalValueDefValue? Value { get; set; }
+        public ConditionalValueDefValue Value { get; set; }
 
         /// <summary>
         /// A [selection name](selection.html), or a series of [composed
         /// selections](selection.html#compose).
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("selection")]
-        public SelectionOperand? Selection { get; set; }
+        public SelectionOperand Selection { get; set; }
 
         /// <summary>
         /// Aggregation function for the field
@@ -5598,9 +5598,9 @@ namespace QuickType
         /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
         /// [geographic projection](projection.html) is applied.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("type")]
-        public ConditionalPredicateValueDefType? Type { get; set; }
+        public ConditionalPredicateValueDefType Type { get; set; }
     }
 
     public partial class OrderFieldDef
@@ -5763,9 +5763,9 @@ namespace QuickType
         /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
         /// [geographic projection](projection.html) is applied.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("type")]
-        public ConditionalPredicateValueDefType? Type { get; set; }
+        public ConditionalPredicateValueDefType Type { get; set; }
 
         /// <summary>
         /// A constant value in visual domain.
@@ -5777,25 +5777,25 @@ namespace QuickType
 
     public partial class ConditionalPredicateTextFieldDefClass
     {
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("test")]
-        public LogicalOperandPredicate? Test { get; set; }
+        public LogicalOperandPredicate Test { get; set; }
 
         /// <summary>
         /// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
         /// `0` to `1` for opacity).
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("value")]
-        public ConditionalValueDefValue? Value { get; set; }
+        public ConditionalValueDefValue Value { get; set; }
 
         /// <summary>
         /// A [selection name](selection.html), or a series of [composed
         /// selections](selection.html#compose).
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("selection")]
-        public SelectionOperand? Selection { get; set; }
+        public SelectionOperand Selection { get; set; }
 
         /// <summary>
         /// Aggregation function for the field
@@ -5858,9 +5858,9 @@ namespace QuickType
         /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
         /// [geographic projection](projection.html) is applied.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("type")]
-        public ConditionalPredicateValueDefType? Type { get; set; }
+        public ConditionalPredicateValueDefType Type { get; set; }
     }
 
     /// <summary>
@@ -5981,17 +5981,17 @@ namespace QuickType
         /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
         /// [geographic projection](projection.html) is applied.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("type")]
-        public ConditionalPredicateValueDefType? Type { get; set; }
+        public ConditionalPredicateValueDefType Type { get; set; }
 
         /// <summary>
         /// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
         /// `0` to `1` for opacity).
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("value")]
-        public ConditionalValueDefValue? Value { get; set; }
+        public ConditionalValueDefValue Value { get; set; }
     }
 
     public partial class Axis
@@ -6293,17 +6293,17 @@ namespace QuickType
         /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
         /// [geographic projection](projection.html) is applied.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("type")]
-        public ConditionalPredicateValueDefType? Type { get; set; }
+        public ConditionalPredicateValueDefType Type { get; set; }
 
         /// <summary>
         /// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
         /// `0` to `1` for opacity).
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("value")]
-        public ConditionalValueDefValue? Value { get; set; }
+        public ConditionalValueDefValue Value { get; set; }
     }
 
     /// <summary>
@@ -6375,9 +6375,9 @@ namespace QuickType
         /// __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
         /// layering facet specifications is not allowed.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("layer")]
-        public LayerSpec[]? Layer { get; set; }
+        public LayerSpec[] Layer { get; set; }
 
         /// <summary>
         /// Name of the visualization for later reference.
@@ -6444,9 +6444,9 @@ namespace QuickType
         /// <summary>
         /// A key-value mapping between encoding channels and definition of fields.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("encoding")]
-        public Encoding? Encoding { get; set; }
+        public Encoding Encoding { get; set; }
 
         /// <summary>
         /// A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
@@ -6454,9 +6454,9 @@ namespace QuickType
         /// * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
         /// object](mark.html#mark-def).
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("mark")]
-        public AnyMark? Mark { get; set; }
+        public AnyMark Mark { get; set; }
 
         /// <summary>
         /// An object defining properties of geographic projection.
@@ -6479,38 +6479,38 @@ namespace QuickType
         /// An object that describes mappings between `row` and `column` channels and their field
         /// definitions.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("facet")]
-        public FacetMapping? Facet { get; set; }
+        public FacetMapping Facet { get; set; }
 
         /// <summary>
         /// A specification of the view that gets faceted.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("spec")]
-        public Spec? SpecSpec { get; set; }
+        public Spec SpecSpec { get; set; }
 
         /// <summary>
         /// An object that describes what fields should be repeated into views that are laid out as a
         /// `row` or `column`.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("repeat")]
-        public Repeat? Repeat { get; set; }
+        public Repeat Repeat { get; set; }
 
         /// <summary>
         /// A list of views that should be concatenated and put into a column.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("vconcat")]
-        public Spec[]? Vconcat { get; set; }
+        public Spec[] Vconcat { get; set; }
 
         /// <summary>
         /// A list of views that should be concatenated and put into a row.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("hconcat")]
-        public Spec[]? Hconcat { get; set; }
+        public Spec[] Hconcat { get; set; }
     }
 
     /// <summary>
@@ -6684,9 +6684,9 @@ namespace QuickType
         /// __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
         /// layering facet specifications is not allowed.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("layer")]
-        public LayerSpec[]? Layer { get; set; }
+        public LayerSpec[] Layer { get; set; }
 
         /// <summary>
         /// Name of the visualization for later reference.
@@ -6745,9 +6745,9 @@ namespace QuickType
         /// <summary>
         /// A key-value mapping between encoding channels and definition of fields.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("encoding")]
-        public Encoding? Encoding { get; set; }
+        public Encoding Encoding { get; set; }
 
         /// <summary>
         /// A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
@@ -6755,9 +6755,9 @@ namespace QuickType
         /// * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
         /// object](mark.html#mark-def).
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("mark")]
-        public AnyMark? Mark { get; set; }
+        public AnyMark Mark { get; set; }
 
         /// <summary>
         /// An object defining properties of geographic projection.
@@ -7479,9 +7479,9 @@ namespace QuickType
         /// (3) a [selection predicate](filter.html#selection-predicate);
         /// or (4) a logical operand that combines (1), (2), or (3).
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("filter")]
-        public LogicalOperandPredicate? Filter { get; set; }
+        public LogicalOperandPredicate Filter { get; set; }
 
         /// <summary>
         /// The field for storing the computed formula value.
@@ -7503,9 +7503,9 @@ namespace QuickType
         /// A [expression](types.html#expression) string. Use the variable `datum` to refer to the
         /// current data object.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("calculate")]
-        public string? Calculate { get; set; }
+        public string Calculate { get; set; }
 
         /// <summary>
         /// The default value to use if lookup fails.
@@ -7519,46 +7519,46 @@ namespace QuickType
         /// <summary>
         /// Secondary data reference.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("from")]
-        public LookupData? From { get; set; }
+        public LookupData From { get; set; }
 
         /// <summary>
         /// Key in primary data source.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("lookup")]
-        public string? Lookup { get; set; }
+        public string Lookup { get; set; }
 
         /// <summary>
         /// An object indicating bin properties, or simply `true` for using default bin parameters.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("bin")]
-        public Bin? Bin { get; set; }
+        public Bin Bin { get; set; }
 
         /// <summary>
         /// The data field to bin.
         ///
         /// The data field to apply time unit.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("field")]
-        public string? Field { get; set; }
+        public string Field { get; set; }
 
         /// <summary>
         /// The timeUnit.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("timeUnit")]
-        public TimeUnit? TimeUnit { get; set; }
+        public TimeUnit TimeUnit { get; set; }
 
         /// <summary>
         /// Array of objects that define fields to aggregate.
         /// </summary>
-        [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+        [JsonRequired]
         [JsonPropertyName("aggregate")]
-        public AggregatedFieldDef[]? Aggregate { get; set; }
+        public AggregatedFieldDef[] Aggregate { get; set; }
 
         /// <summary>
         /// The data fields to group by. If not specified, a single group containing all data objects
diff --git a/head/schema-csharp-records/test/inputs/schema/required-in-any-of.schema/default/QuickType.cs b/head/schema-csharp-records/test/inputs/schema/required-in-any-of.schema/default/QuickType.cs
new file mode 100644
index 0000000..ee4fad9
--- /dev/null
+++ b/head/schema-csharp-records/test/inputs/schema/required-in-any-of.schema/default/QuickType.cs
@@ -0,0 +1,70 @@
+// <auto-generated />
+//
+// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
+//
+//    using QuickType;
+//
+//    var topLevel = TopLevel.FromJson(jsonString);
+#nullable enable
+#pragma warning disable CS8618
+#pragma warning disable CS8601
+#pragma warning disable CS8602
+#pragma warning disable CS8603
+#pragma warning disable CS8604
+#pragma warning disable CS8625
+#pragma warning disable CS8765
+
+namespace QuickType
+{
+    using System;
+    using System.Collections.Generic;
+
+    using System.Globalization;
+    using Newtonsoft.Json;
+    using Newtonsoft.Json.Converters;
+
+    public partial record TopLevel
+    {
+        [JsonProperty("anyof", Required = Required.Always)]
+        public Anyof Anyof { get; set; }
+    }
+
+    public partial record Anyof
+    {
+        [JsonProperty("name", Required = Required.Always)]
+        public string Name { get; set; }
+
+        [JsonProperty("size", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
+        public string? Size { get; set; }
+    }
+
+    public partial record TopLevel
+    {
+        public static TopLevel FromJson(string json) => JsonConvert.DeserializeObject<TopLevel>(json, QuickType.Converter.Settings);
+    }
+
+    public static partial class Serialize
+    {
+        public static string ToJson(this TopLevel self) => JsonConvert.SerializeObject(self, QuickType.Converter.Settings);
+    }
+
+    internal static partial class Converter
+    {
+        public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
+        {
+            MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
+            DateParseHandling = DateParseHandling.None,
+            Converters =
+            {
+                new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
+            },
+        };
+    }
+}
+#pragma warning restore CS8618
+#pragma warning restore CS8601
+#pragma warning restore CS8602
+#pragma warning restore CS8603
+#pragma warning restore CS8604
+#pragma warning restore CS8625
+#pragma warning restore CS8765
diff --git a/base/schema-csharp-records/test/inputs/schema/vega-lite.schema/default/QuickType.cs b/head/schema-csharp-records/test/inputs/schema/vega-lite.schema/default/QuickType.cs
index a1ba5ce..0aaca1b 100644
--- a/base/schema-csharp-records/test/inputs/schema/vega-lite.schema/default/QuickType.cs
+++ b/head/schema-csharp-records/test/inputs/schema/vega-lite.schema/default/QuickType.cs
@@ -76,8 +76,8 @@ namespace QuickType
         /// <summary>
         /// A key-value mapping between encoding channels and definition of fields.
         /// </summary>
-        [JsonProperty("encoding", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public EncodingWithFacet? Encoding { get; set; }
+        [JsonProperty("encoding", Required = Required.Always)]
+        public EncodingWithFacet Encoding { get; set; }
 
         /// <summary>
         /// The height of a visualization.
@@ -107,8 +107,8 @@ namespace QuickType
         /// * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
         /// object](mark.html#mark-def).
         /// </summary>
-        [JsonProperty("mark", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public AnyMark? Mark { get; set; }
+        [JsonProperty("mark", Required = Required.Always)]
+        public AnyMark Mark { get; set; }
 
         /// <summary>
         /// Name of the visualization for later reference.
@@ -185,8 +185,8 @@ namespace QuickType
         /// __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
         /// layering facet specifications is not allowed.
         /// </summary>
-        [JsonProperty("layer", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public LayerSpec[]? Layer { get; set; }
+        [JsonProperty("layer", Required = Required.Always)]
+        public LayerSpec[] Layer { get; set; }
 
         /// <summary>
         /// Scale, axis, and legend resolutions for layers.
@@ -206,33 +206,33 @@ namespace QuickType
         /// An object that describes mappings between `row` and `column` channels and their field
         /// definitions.
         /// </summary>
-        [JsonProperty("facet", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public FacetMapping? Facet { get; set; }
+        [JsonProperty("facet", Required = Required.Always)]
+        public FacetMapping Facet { get; set; }
 
         /// <summary>
         /// A specification of the view that gets faceted.
         /// </summary>
-        [JsonProperty("spec", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Spec? Spec { get; set; }
+        [JsonProperty("spec", Required = Required.Always)]
+        public Spec Spec { get; set; }
 
         /// <summary>
         /// An object that describes what fields should be repeated into views that are laid out as a
         /// `row` or `column`.
         /// </summary>
-        [JsonProperty("repeat", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Repeat? Repeat { get; set; }
+        [JsonProperty("repeat", Required = Required.Always)]
+        public Repeat Repeat { get; set; }
 
         /// <summary>
         /// A list of views that should be concatenated and put into a column.
         /// </summary>
-        [JsonProperty("vconcat", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Spec[]? Vconcat { get; set; }
+        [JsonProperty("vconcat", Required = Required.Always)]
+        public Spec[] Vconcat { get; set; }
 
         /// <summary>
         /// A list of views that should be concatenated and put into a row.
         /// </summary>
-        [JsonProperty("hconcat", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Spec[]? Hconcat { get; set; }
+        [JsonProperty("hconcat", Required = Required.Always)]
+        public Spec[] Hconcat { get; set; }
     }
 
     public partial record AutoSizeParams
@@ -2061,8 +2061,8 @@ namespace QuickType
         [JsonProperty("extent", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
         public double[]? Extent { get; set; }
 
-        [JsonProperty("scheme", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public string? Scheme { get; set; }
+        [JsonProperty("scheme", Required = Required.Always)]
+        public string Scheme { get; set; }
 
         [JsonProperty("step", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
         public double? Step { get; set; }
@@ -2587,8 +2587,8 @@ namespace QuickType
         [JsonProperty("input", Required = Required.Always)]
         public string Input { get; set; }
 
-        [JsonProperty("options", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public string[]? Options { get; set; }
+        [JsonProperty("options", Required = Required.Always)]
+        public string[] Options { get; set; }
 
         [JsonProperty("max", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
         public double? Max { get; set; }
@@ -3564,8 +3564,8 @@ namespace QuickType
         /// An URL from which to load the data set. Use the `format.type` property
         /// to ensure the loaded data is correctly parsed.
         /// </summary>
-        [JsonProperty("url", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public string? Url { get; set; }
+        [JsonProperty("url", Required = Required.Always)]
+        public string Url { get; set; }
 
         /// <summary>
         /// The full data set, included inline. This can be an array of objects or primitive values
@@ -3573,14 +3573,14 @@ namespace QuickType
         /// Arrays of primitive values are ingested as objects with a `data` property. Strings are
         /// parsed according to the specified format type.
         /// </summary>
-        [JsonProperty("values", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Values? Values { get; set; }
+        [JsonProperty("values", Required = Required.Always)]
+        public Values Values { get; set; }
 
         /// <summary>
         /// Provide a placeholder name and bind data at runtime.
         /// </summary>
-        [JsonProperty("name", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public string? Name { get; set; }
+        [JsonProperty("name", Required = Required.Always)]
+        public string Name { get; set; }
     }
 
     /// <summary>
@@ -3910,8 +3910,8 @@ namespace QuickType
         /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
         /// [geographic projection](projection.html) is applied.
         /// </summary>
-        [JsonProperty("type", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalPredicateValueDefType? Type { get; set; }
+        [JsonProperty("type", Required = Required.Always)]
+        public ConditionalPredicateValueDefType Type { get; set; }
 
         /// <summary>
         /// A constant value in visual domain.
@@ -3990,8 +3990,8 @@ namespace QuickType
 
     public partial record ConditionalValueDef
     {
-        [JsonProperty("test", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public LogicalOperandPredicate? Test { get; set; }
+        [JsonProperty("test", Required = Required.Always)]
+        public LogicalOperandPredicate Test { get; set; }
 
         /// <summary>
         /// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
@@ -4004,46 +4004,46 @@ namespace QuickType
         /// A [selection name](selection.html), or a series of [composed
         /// selections](selection.html#compose).
         /// </summary>
-        [JsonProperty("selection", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public SelectionOperand? Selection { get; set; }
+        [JsonProperty("selection", Required = Required.Always)]
+        public SelectionOperand Selection { get; set; }
     }
 
     public partial record Selection
     {
-        [JsonProperty("not", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public SelectionOperand? Not { get; set; }
+        [JsonProperty("not", Required = Required.Always)]
+        public SelectionOperand Not { get; set; }
 
-        [JsonProperty("and", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public SelectionOperand[]? And { get; set; }
+        [JsonProperty("and", Required = Required.Always)]
+        public SelectionOperand[] And { get; set; }
 
-        [JsonProperty("or", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public SelectionOperand[]? Or { get; set; }
+        [JsonProperty("or", Required = Required.Always)]
+        public SelectionOperand[] Or { get; set; }
     }
 
     public partial record Predicate
     {
-        [JsonProperty("not", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public LogicalOperandPredicate? Not { get; set; }
+        [JsonProperty("not", Required = Required.Always)]
+        public LogicalOperandPredicate Not { get; set; }
 
-        [JsonProperty("and", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public LogicalOperandPredicate[]? And { get; set; }
+        [JsonProperty("and", Required = Required.Always)]
+        public LogicalOperandPredicate[] And { get; set; }
 
-        [JsonProperty("or", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public LogicalOperandPredicate[]? Or { get; set; }
+        [JsonProperty("or", Required = Required.Always)]
+        public LogicalOperandPredicate[] Or { get; set; }
 
         /// <summary>
         /// The value that the field should be equal to.
         /// </summary>
-        [JsonProperty("equal", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Equal? Equal { get; set; }
+        [JsonProperty("equal", Required = Required.Always)]
+        public Equal Equal { get; set; }
 
         /// <summary>
         /// Field to be filtered.
         ///
         /// Field to be filtered
         /// </summary>
-        [JsonProperty("field", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public string? Field { get; set; }
+        [JsonProperty("field", Required = Required.Always)]
+        public string Field { get; set; }
 
         /// <summary>
         /// Time unit for the field to be filtered.
@@ -4057,21 +4057,21 @@ namespace QuickType
         /// An array of inclusive minimum and maximum values
         /// for a field value of a data item to be included in the filtered data.
         /// </summary>
-        [JsonProperty("range", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public RangeElement[]? Range { get; set; }
+        [JsonProperty("range", Required = Required.Always)]
+        public RangeElement[] Range { get; set; }
 
         /// <summary>
         /// A set of values that the `field`'s value should be a member of,
         /// for a data item included in the filtered data.
         /// </summary>
-        [JsonProperty("oneOf", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Equal[]? OneOf { get; set; }
+        [JsonProperty("oneOf", Required = Required.Always)]
+        public Equal[] OneOf { get; set; }
 
         /// <summary>
         /// Filter using a selection name.
         /// </summary>
-        [JsonProperty("selection", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public SelectionOperand? Selection { get; set; }
+        [JsonProperty("selection", Required = Required.Always)]
+        public SelectionOperand Selection { get; set; }
     }
 
     /// <summary>
@@ -4158,22 +4158,22 @@ namespace QuickType
 
     public partial record ConditionalPredicateMarkPropFieldDefClass
     {
-        [JsonProperty("test", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public LogicalOperandPredicate? Test { get; set; }
+        [JsonProperty("test", Required = Required.Always)]
+        public LogicalOperandPredicate Test { get; set; }
 
         /// <summary>
         /// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
         /// `0` to `1` for opacity).
         /// </summary>
-        [JsonProperty("value", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalValueDefValue? Value { get; set; }
+        [JsonProperty("value", Required = Required.Always)]
+        public ConditionalValueDefValue Value { get; set; }
 
         /// <summary>
         /// A [selection name](selection.html), or a series of [composed
         /// selections](selection.html#compose).
         /// </summary>
-        [JsonProperty("selection", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public SelectionOperand? Selection { get; set; }
+        [JsonProperty("selection", Required = Required.Always)]
+        public SelectionOperand Selection { get; set; }
 
         /// <summary>
         /// Aggregation function for the field
@@ -4254,8 +4254,8 @@ namespace QuickType
         /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
         /// [geographic projection](projection.html) is applied.
         /// </summary>
-        [JsonProperty("type", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalPredicateValueDefType? Type { get; set; }
+        [JsonProperty("type", Required = Required.Always)]
+        public ConditionalPredicateValueDefType Type { get; set; }
     }
 
     /// <summary>
@@ -4960,8 +4960,8 @@ namespace QuickType
         /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
         /// [geographic projection](projection.html) is applied.
         /// </summary>
-        [JsonProperty("type", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalPredicateValueDefType? Type { get; set; }
+        [JsonProperty("type", Required = Required.Always)]
+        public ConditionalPredicateValueDefType Type { get; set; }
 
         /// <summary>
         /// A constant value in visual domain.
@@ -4972,22 +4972,22 @@ namespace QuickType
 
     public partial record ConditionalPredicateFieldDefClass
     {
-        [JsonProperty("test", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public LogicalOperandPredicate? Test { get; set; }
+        [JsonProperty("test", Required = Required.Always)]
+        public LogicalOperandPredicate Test { get; set; }
 
         /// <summary>
         /// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
         /// `0` to `1` for opacity).
         /// </summary>
-        [JsonProperty("value", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalValueDefValue? Value { get; set; }
+        [JsonProperty("value", Required = Required.Always)]
+        public ConditionalValueDefValue Value { get; set; }
 
         /// <summary>
         /// A [selection name](selection.html), or a series of [composed
         /// selections](selection.html#compose).
         /// </summary>
-        [JsonProperty("selection", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public SelectionOperand? Selection { get; set; }
+        [JsonProperty("selection", Required = Required.Always)]
+        public SelectionOperand Selection { get; set; }
 
         /// <summary>
         /// Aggregation function for the field
@@ -5038,8 +5038,8 @@ namespace QuickType
         /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
         /// [geographic projection](projection.html) is applied.
         /// </summary>
-        [JsonProperty("type", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalPredicateValueDefType? Type { get; set; }
+        [JsonProperty("type", Required = Required.Always)]
+        public ConditionalPredicateValueDefType Type { get; set; }
     }
 
     public partial record OrderFieldDef
@@ -5191,8 +5191,8 @@ namespace QuickType
         /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
         /// [geographic projection](projection.html) is applied.
         /// </summary>
-        [JsonProperty("type", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalPredicateValueDefType? Type { get; set; }
+        [JsonProperty("type", Required = Required.Always)]
+        public ConditionalPredicateValueDefType Type { get; set; }
 
         /// <summary>
         /// A constant value in visual domain.
@@ -5203,22 +5203,22 @@ namespace QuickType
 
     public partial record ConditionalPredicateTextFieldDefClass
     {
-        [JsonProperty("test", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public LogicalOperandPredicate? Test { get; set; }
+        [JsonProperty("test", Required = Required.Always)]
+        public LogicalOperandPredicate Test { get; set; }
 
         /// <summary>
         /// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
         /// `0` to `1` for opacity).
         /// </summary>
-        [JsonProperty("value", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalValueDefValue? Value { get; set; }
+        [JsonProperty("value", Required = Required.Always)]
+        public ConditionalValueDefValue Value { get; set; }
 
         /// <summary>
         /// A [selection name](selection.html), or a series of [composed
         /// selections](selection.html#compose).
         /// </summary>
-        [JsonProperty("selection", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public SelectionOperand? Selection { get; set; }
+        [JsonProperty("selection", Required = Required.Always)]
+        public SelectionOperand Selection { get; set; }
 
         /// <summary>
         /// Aggregation function for the field
@@ -5276,8 +5276,8 @@ namespace QuickType
         /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
         /// [geographic projection](projection.html) is applied.
         /// </summary>
-        [JsonProperty("type", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalPredicateValueDefType? Type { get; set; }
+        [JsonProperty("type", Required = Required.Always)]
+        public ConditionalPredicateValueDefType Type { get; set; }
     }
 
     /// <summary>
@@ -5393,15 +5393,15 @@ namespace QuickType
         /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
         /// [geographic projection](projection.html) is applied.
         /// </summary>
-        [JsonProperty("type", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalPredicateValueDefType? Type { get; set; }
+        [JsonProperty("type", Required = Required.Always)]
+        public ConditionalPredicateValueDefType Type { get; set; }
 
         /// <summary>
         /// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
         /// `0` to `1` for opacity).
         /// </summary>
-        [JsonProperty("value", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalValueDefValue? Value { get; set; }
+        [JsonProperty("value", Required = Required.Always)]
+        public ConditionalValueDefValue Value { get; set; }
     }
 
     public partial record Axis
@@ -5678,15 +5678,15 @@ namespace QuickType
         /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
         /// [geographic projection](projection.html) is applied.
         /// </summary>
-        [JsonProperty("type", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalPredicateValueDefType? Type { get; set; }
+        [JsonProperty("type", Required = Required.Always)]
+        public ConditionalPredicateValueDefType Type { get; set; }
 
         /// <summary>
         /// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
         /// `0` to `1` for opacity).
         /// </summary>
-        [JsonProperty("value", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public ConditionalValueDefValue? Value { get; set; }
+        [JsonProperty("value", Required = Required.Always)]
+        public ConditionalValueDefValue Value { get; set; }
     }
 
     /// <summary>
@@ -5753,8 +5753,8 @@ namespace QuickType
         /// __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
         /// layering facet specifications is not allowed.
         /// </summary>
-        [JsonProperty("layer", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public LayerSpec[]? Layer { get; set; }
+        [JsonProperty("layer", Required = Required.Always)]
+        public LayerSpec[] Layer { get; set; }
 
         /// <summary>
         /// Name of the visualization for later reference.
@@ -5816,8 +5816,8 @@ namespace QuickType
         /// <summary>
         /// A key-value mapping between encoding channels and definition of fields.
         /// </summary>
-        [JsonProperty("encoding", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Encoding? Encoding { get; set; }
+        [JsonProperty("encoding", Required = Required.Always)]
+        public Encoding Encoding { get; set; }
 
         /// <summary>
         /// A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
@@ -5825,8 +5825,8 @@ namespace QuickType
         /// * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
         /// object](mark.html#mark-def).
         /// </summary>
-        [JsonProperty("mark", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public AnyMark? Mark { get; set; }
+        [JsonProperty("mark", Required = Required.Always)]
+        public AnyMark Mark { get; set; }
 
         /// <summary>
         /// An object defining properties of geographic projection.
@@ -5847,33 +5847,33 @@ namespace QuickType
         /// An object that describes mappings between `row` and `column` channels and their field
         /// definitions.
         /// </summary>
-        [JsonProperty("facet", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public FacetMapping? Facet { get; set; }
+        [JsonProperty("facet", Required = Required.Always)]
+        public FacetMapping Facet { get; set; }
 
         /// <summary>
         /// A specification of the view that gets faceted.
         /// </summary>
-        [JsonProperty("spec", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Spec? SpecSpec { get; set; }
+        [JsonProperty("spec", Required = Required.Always)]
+        public Spec SpecSpec { get; set; }
 
         /// <summary>
         /// An object that describes what fields should be repeated into views that are laid out as a
         /// `row` or `column`.
         /// </summary>
-        [JsonProperty("repeat", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Repeat? Repeat { get; set; }
+        [JsonProperty("repeat", Required = Required.Always)]
+        public Repeat Repeat { get; set; }
 
         /// <summary>
         /// A list of views that should be concatenated and put into a column.
         /// </summary>
-        [JsonProperty("vconcat", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Spec[]? Vconcat { get; set; }
+        [JsonProperty("vconcat", Required = Required.Always)]
+        public Spec[] Vconcat { get; set; }
 
         /// <summary>
         /// A list of views that should be concatenated and put into a row.
         /// </summary>
-        [JsonProperty("hconcat", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Spec[]? Hconcat { get; set; }
+        [JsonProperty("hconcat", Required = Required.Always)]
+        public Spec[] Hconcat { get; set; }
     }
 
     /// <summary>
@@ -6031,8 +6031,8 @@ namespace QuickType
         /// __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
         /// layering facet specifications is not allowed.
         /// </summary>
-        [JsonProperty("layer", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public LayerSpec[]? Layer { get; set; }
+        [JsonProperty("layer", Required = Required.Always)]
+        public LayerSpec[] Layer { get; set; }
 
         /// <summary>
         /// Name of the visualization for later reference.
@@ -6086,8 +6086,8 @@ namespace QuickType
         /// <summary>
         /// A key-value mapping between encoding channels and definition of fields.
         /// </summary>
-        [JsonProperty("encoding", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Encoding? Encoding { get; set; }
+        [JsonProperty("encoding", Required = Required.Always)]
+        public Encoding Encoding { get; set; }
 
         /// <summary>
         /// A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
@@ -6095,8 +6095,8 @@ namespace QuickType
         /// * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
         /// object](mark.html#mark-def).
         /// </summary>
-        [JsonProperty("mark", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public AnyMark? Mark { get; set; }
+        [JsonProperty("mark", Required = Required.Always)]
+        public AnyMark Mark { get; set; }
 
         /// <summary>
         /// An object defining properties of geographic projection.
@@ -6737,8 +6737,8 @@ namespace QuickType
         /// (3) a [selection predicate](filter.html#selection-predicate);
         /// or (4) a logical operand that combines (1), (2), or (3).
         /// </summary>
-        [JsonProperty("filter", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public LogicalOperandPredicate? Filter { get; set; }
+        [JsonProperty("filter", Required = Required.Always)]
+        public LogicalOperandPredicate Filter { get; set; }
 
         /// <summary>
         /// The field for storing the computed formula value.
@@ -6759,8 +6759,8 @@ namespace QuickType
         /// A [expression](types.html#expression) string. Use the variable `datum` to refer to the
         /// current data object.
         /// </summary>
-        [JsonProperty("calculate", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public string? Calculate { get; set; }
+        [JsonProperty("calculate", Required = Required.Always)]
+        public string Calculate { get; set; }
 
         /// <summary>
         /// The default value to use if lookup fails.
@@ -6773,40 +6773,40 @@ namespace QuickType
         /// <summary>
         /// Secondary data reference.
         /// </summary>
-        [JsonProperty("from", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public LookupData? From { get; set; }
+        [JsonProperty("from", Required = Required.Always)]
+        public LookupData From { get; set; }
 
         /// <summary>
         /// Key in primary data source.
         /// </summary>
-        [JsonProperty("lookup", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public string? Lookup { get; set; }
+        [JsonProperty("lookup", Required = Required.Always)]
+        public string Lookup { get; set; }
 
         /// <summary>
         /// An object indicating bin properties, or simply `true` for using default bin parameters.
         /// </summary>
-        [JsonProperty("bin", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public Bin? Bin { get; set; }
+        [JsonProperty("bin", Required = Required.Always)]
+        public Bin Bin { get; set; }
 
         /// <summary>
         /// The data field to bin.
         ///
         /// The data field to apply time unit.
         /// </summary>
-        [JsonProperty("field", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public string? Field { get; set; }
+        [JsonProperty("field", Required = Required.Always)]
+        public string Field { get; set; }
 
         /// <summary>
         /// The timeUnit.
         /// </summary>
-        [JsonProperty("timeUnit", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public TimeUnit? TimeUnit { get; set; }
+        [JsonProperty("timeUnit", Required = Required.Always)]
+        public TimeUnit TimeUnit { get; set; }
 
         /// <summary>
         /// Array of objects that define fields to aggregate.
         /// </summary>
-        [JsonProperty("aggregate", Required = Required.DisallowNull, NullValueHandling = NullValueHandling.Ignore)]
-        public AggregatedFieldDef[]? Aggregate { get; set; }
+        [JsonProperty("aggregate", Required = Required.Always)]
+        public AggregatedFieldDef[] Aggregate { get; set; }
 
         /// <summary>
         /// The data fields to group by. If not specified, a single group containing all data objects
diff --git a/head/schema-dart/test/inputs/schema/required-in-any-of.schema/default/TopLevel.dart b/head/schema-dart/test/inputs/schema/required-in-any-of.schema/default/TopLevel.dart
new file mode 100644
index 0000000..1f3490e
--- /dev/null
+++ b/head/schema-dart/test/inputs/schema/required-in-any-of.schema/default/TopLevel.dart
@@ -0,0 +1,45 @@
+// To parse this JSON data, do
+//
+//     final topLevel = topLevelFromJson(jsonString);
+
+import 'dart:convert';
+
+TopLevel topLevelFromJson(String str) => TopLevel.fromJson(json.decode(str));
+
+String topLevelToJson(TopLevel data) => json.encode(data.toJson());
+
+class TopLevel {
+    final Anyof anyof;
+
+    TopLevel({
+        required this.anyof,
+    });
+
+    factory TopLevel.fromJson(Map<String, dynamic> json) => TopLevel(
+        anyof: Anyof.fromJson(json["anyof"]),
+    );
+
+    Map<String, dynamic> toJson() => {
+        "anyof": anyof.toJson(),
+    };
+}
+
+class Anyof {
+    final String name;
+    final String? size;
+
+    Anyof({
+        required this.name,
+        this.size,
+    });
+
+    factory Anyof.fromJson(Map<String, dynamic> json) => Anyof(
+        name: json["name"],
+        size: json["size"],
+    );
+
+    Map<String, dynamic> toJson() => {
+        "name": name,
+        "size": size,
+    };
+}
diff --git a/base/schema-dart/test/inputs/schema/vega-lite.schema/default/TopLevel.dart b/head/schema-dart/test/inputs/schema/vega-lite.schema/default/TopLevel.dart
index e65602f..d6accc3 100644
--- a/base/schema-dart/test/inputs/schema/vega-lite.schema/default/TopLevel.dart
+++ b/head/schema-dart/test/inputs/schema/vega-lite.schema/default/TopLevel.dart
@@ -41,7 +41,7 @@ class TopLevel {
     final String? description;
     
     ///A key-value mapping between encoding channels and definition of fields.
-    final EncodingWithFacet? encoding;
+    final EncodingWithFacet encoding;
     
     ///The height of a visualization.
     ///
@@ -120,7 +120,7 @@ class TopLevel {
     ///
     ///__Note__: Specifications inside `layer` cannot use `row` and `column` channels as
     ///layering facet specifications is not allowed.
-    final List<LayerSpec>? layer;
+    final List<LayerSpec> layer;
     
     ///Scale, axis, and legend resolutions for layers.
     ///
@@ -135,20 +135,20 @@ class TopLevel {
     
     ///An object that describes mappings between `row` and `column` channels and their field
     ///definitions.
-    final FacetMapping? facet;
+    final FacetMapping facet;
     
     ///A specification of the view that gets faceted.
-    final Spec? spec;
+    final Spec spec;
     
     ///An object that describes what fields should be repeated into views that are laid out as a
     ///`row` or `column`.
-    final Repeat? repeat;
+    final Repeat repeat;
     
     ///A list of views that should be concatenated and put into a column.
-    final List<Spec>? vconcat;
+    final List<Spec> vconcat;
     
     ///A list of views that should be concatenated and put into a row.
-    final List<Spec>? hconcat;
+    final List<Spec> hconcat;
 
     TopLevel({
         this.schema,
@@ -157,9 +157,9 @@ class TopLevel {
         this.config,
         this.data,
         this.description,
-        this.encoding,
+        required this.encoding,
         this.height,
-        this.mark,
+        required this.mark,
         this.name,
         this.padding,
         this.projection,
@@ -167,13 +167,13 @@ class TopLevel {
         this.title,
         this.transform,
         this.width,
-        this.layer,
+        required this.layer,
         this.resolve,
-        this.facet,
-        this.spec,
-        this.repeat,
-        this.vconcat,
-        this.hconcat,
+        required this.facet,
+        required this.spec,
+        required this.repeat,
+        required this.vconcat,
+        required this.hconcat,
     });
 
     factory TopLevel.fromJson(Map<String, dynamic> json) => TopLevel(
@@ -183,7 +183,7 @@ class TopLevel {
         config: json["config"] == null ? null : Config.fromJson(json["config"]),
         data: json["data"] == null ? null : Data.fromJson(json["data"]),
         description: json["description"],
-        encoding: json["encoding"] == null ? null : EncodingWithFacet.fromJson(json["encoding"]),
+        encoding: EncodingWithFacet.fromJson(json["encoding"]),
         height: json["height"]?.toDouble(),
         mark: json["mark"],
         name: json["name"],
@@ -193,13 +193,13 @@ class TopLevel {
         title: json["title"],
         transform: json["transform"] == null ? null : List<Transform>.from(json["transform"]!.map((x) => Transform.fromJson(x))),
         width: json["width"]?.toDouble(),
-        layer: json["layer"] == null ? null : List<LayerSpec>.from(json["layer"]!.map((x) => LayerSpec.fromJson(x))),
+        layer: List<LayerSpec>.from(json["layer"].map((x) => LayerSpec.fromJson(x))),
         resolve: json["resolve"] == null ? null : Resolve.fromJson(json["resolve"]),
-        facet: json["facet"] == null ? null : FacetMapping.fromJson(json["facet"]),
-        spec: json["spec"] == null ? null : Spec.fromJson(json["spec"]),
-        repeat: json["repeat"] == null ? null : Repeat.fromJson(json["repeat"]),
-        vconcat: json["vconcat"] == null ? null : List<Spec>.from(json["vconcat"]!.map((x) => Spec.fromJson(x))),
-        hconcat: json["hconcat"] == null ? null : List<Spec>.from(json["hconcat"]!.map((x) => Spec.fromJson(x))),
+        facet: FacetMapping.fromJson(json["facet"]),
+        spec: Spec.fromJson(json["spec"]),
+        repeat: Repeat.fromJson(json["repeat"]),
+        vconcat: List<Spec>.from(json["vconcat"].map((x) => Spec.fromJson(x))),
+        hconcat: List<Spec>.from(json["hconcat"].map((x) => Spec.fromJson(x))),
     );
 
     Map<String, dynamic> toJson() => {
@@ -209,7 +209,7 @@ class TopLevel {
         "config": config?.toJson(),
         "data": data?.toJson(),
         "description": description,
-        "encoding": encoding?.toJson(),
+        "encoding": encoding.toJson(),
         "height": height,
         "mark": mark,
         "name": name,
@@ -219,13 +219,13 @@ class TopLevel {
         "title": title,
         "transform": transform == null ? null : List<dynamic>.from(transform!.map((x) => x.toJson())),
         "width": width,
-        "layer": layer == null ? null : List<dynamic>.from(layer!.map((x) => x.toJson())),
+        "layer": List<dynamic>.from(layer.map((x) => x.toJson())),
         "resolve": resolve?.toJson(),
-        "facet": facet?.toJson(),
-        "spec": spec?.toJson(),
-        "repeat": repeat?.toJson(),
-        "vconcat": vconcat == null ? null : List<dynamic>.from(vconcat!.map((x) => x.toJson())),
-        "hconcat": hconcat == null ? null : List<dynamic>.from(hconcat!.map((x) => x.toJson())),
+        "facet": facet.toJson(),
+        "spec": spec.toJson(),
+        "repeat": repeat.toJson(),
+        "vconcat": List<dynamic>.from(vconcat.map((x) => x.toJson())),
+        "hconcat": List<dynamic>.from(hconcat.map((x) => x.toJson())),
     };
 }
 
@@ -2446,13 +2446,13 @@ final vgProjectionTypeValues = EnumValues({
 class VgScheme {
     final double? count;
     final List<double>? extent;
-    final String? scheme;
+    final String scheme;
     final double? step;
 
     VgScheme({
         this.count,
         this.extent,
-        this.scheme,
+        required this.scheme,
         this.step,
     });
 
@@ -3090,7 +3090,7 @@ class SingleSelectionConfig {
 class VgBinding {
     final String? element;
     final String input;
-    final List<String>? options;
+    final List<String> options;
     final double? max;
     final double? min;
     final double? step;
@@ -3098,7 +3098,7 @@ class VgBinding {
     VgBinding({
         this.element,
         required this.input,
-        this.options,
+        required this.options,
         this.max,
         this.min,
         this.step,
@@ -3107,7 +3107,7 @@ class VgBinding {
     factory VgBinding.fromJson(Map<String, dynamic> json) => VgBinding(
         element: json["element"],
         input: json["input"],
-        options: json["options"] == null ? null : List<String>.from(json["options"]!.map((x) => x)),
+        options: List<String>.from(json["options"].map((x) => x)),
         max: json["max"]?.toDouble(),
         min: json["min"]?.toDouble(),
         step: json["step"]?.toDouble(),
@@ -3116,7 +3116,7 @@ class VgBinding {
     Map<String, dynamic> toJson() => {
         "element": element,
         "input": input,
-        "options": options == null ? null : List<dynamic>.from(options!.map((x) => x)),
+        "options": List<dynamic>.from(options.map((x) => x)),
         "max": max,
         "min": min,
         "step": step,
@@ -4153,7 +4153,7 @@ class Data {
     
     ///An URL from which to load the data set. Use the `format.type` property
     ///to ensure the loaded data is correctly parsed.
-    final String? url;
+    final String url;
     
     ///The full data set, included inline. This can be an array of objects or primitive values
     ///or a string.
@@ -4162,13 +4162,13 @@ class Data {
     final dynamic values;
     
     ///Provide a placeholder name and bind data at runtime.
-    final String? name;
+    final String name;
 
     Data({
         this.format,
-        this.url,
-        this.values,
-        this.name,
+        required this.url,
+        required this.values,
+        required this.name,
     });
 
     factory Data.fromJson(Map<String, dynamic> json) => Data(
@@ -4528,7 +4528,7 @@ class MarkPropDefWithCondition {
     ///`"nominal"`).
     ///It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
     ///[geographic projection](projection.html) is applied.
-    final Type? type;
+    final Type type;
     
     ///A constant value in visual domain.
     final dynamic value;
@@ -4542,7 +4542,7 @@ class MarkPropDefWithCondition {
         this.scale,
         this.sort,
         this.timeUnit,
-        this.type,
+        required this.type,
         this.value,
     });
 
@@ -4555,7 +4555,7 @@ class MarkPropDefWithCondition {
         scale: json["scale"] == null ? null : Scale.fromJson(json["scale"]),
         sort: json["sort"],
         timeUnit: timeUnitValues.map[json["timeUnit"]],
-        type: typeValues.map[json["type"]],
+        type: typeValues.map[json["type"]]!,
         value: json["value"],
     );
 
@@ -4727,9 +4727,9 @@ class ConditionalValueDef {
     final dynamic selection;
 
     ConditionalValueDef({
-        this.test,
+        required this.test,
         required this.value,
-        this.selection,
+        required this.selection,
     });
 
     factory ConditionalValueDef.fromJson(Map<String, dynamic> json) => ConditionalValueDef(
@@ -4747,32 +4747,32 @@ class ConditionalValueDef {
 
 class Selection {
     final dynamic not;
-    final List<dynamic>? and;
-    final List<dynamic>? or;
+    final List<dynamic> and;
+    final List<dynamic> or;
 
     Selection({
-        this.not,
-        this.and,
-        this.or,
+        required this.not,
+        required this.and,
+        required this.or,
     });
 
     factory Selection.fromJson(Map<String, dynamic> json) => Selection(
         not: json["not"],
-        and: json["and"] == null ? null : List<dynamic>.from(json["and"]!.map((x) => x)),
-        or: json["or"] == null ? null : List<dynamic>.from(json["or"]!.map((x) => x)),
+        and: List<dynamic>.from(json["and"].map((x) => x)),
+        or: List<dynamic>.from(json["or"].map((x) => x)),
     );
 
     Map<String, dynamic> toJson() => {
         "not": not,
-        "and": and == null ? null : List<dynamic>.from(and!.map((x) => x)),
-        "or": or == null ? null : List<dynamic>.from(or!.map((x) => x)),
+        "and": List<dynamic>.from(and.map((x) => x)),
+        "or": List<dynamic>.from(or.map((x) => x)),
     };
 }
 
 class Predicate {
     final dynamic not;
-    final List<dynamic>? and;
-    final List<dynamic>? or;
+    final List<dynamic> and;
+    final List<dynamic> or;
     
     ///The value that the field should be equal to.
     final dynamic equal;
@@ -4780,7 +4780,7 @@ class Predicate {
     ///Field to be filtered.
     ///
     ///Field to be filtered
-    final String? field;
+    final String field;
     
     ///Time unit for the field to be filtered.
     ///
@@ -4789,48 +4789,48 @@ class Predicate {
     
     ///An array of inclusive minimum and maximum values
     ///for a field value of a data item to be included in the filtered data.
-    final List<dynamic>? range;
+    final List<dynamic> range;
     
     ///A set of values that the `field`'s value should be a member of,
     ///for a data item included in the filtered data.
-    final List<dynamic>? oneOf;
+    final List<dynamic> oneOf;
     
     ///Filter using a selection name.
     final dynamic selection;
 
     Predicate({
-        this.not,
-        this.and,
-        this.or,
-        this.equal,
-        this.field,
+        required this.not,
+        required this.and,
+        required this.or,
+        required this.equal,
+        required this.field,
         this.timeUnit,
-        this.range,
-        this.oneOf,
-        this.selection,
+        required this.range,
+        required this.oneOf,
+        required this.selection,
     });
 
     factory Predicate.fromJson(Map<String, dynamic> json) => Predicate(
         not: json["not"],
-        and: json["and"] == null ? null : List<dynamic>.from(json["and"]!.map((x) => x)),
-        or: json["or"] == null ? null : List<dynamic>.from(json["or"]!.map((x) => x)),
+        and: List<dynamic>.from(json["and"].map((x) => x)),
+        or: List<dynamic>.from(json["or"].map((x) => x)),
         equal: json["equal"],
         field: json["field"],
         timeUnit: timeUnitValues.map[json["timeUnit"]],
-        range: json["range"] == null ? null : List<dynamic>.from(json["range"]!.map((x) => x)),
-        oneOf: json["oneOf"] == null ? null : List<dynamic>.from(json["oneOf"]!.map((x) => x)),
+        range: List<dynamic>.from(json["range"].map((x) => x)),
+        oneOf: List<dynamic>.from(json["oneOf"].map((x) => x)),
         selection: json["selection"],
     );
 
     Map<String, dynamic> toJson() => {
         "not": not,
-        "and": and == null ? null : List<dynamic>.from(and!.map((x) => x)),
-        "or": or == null ? null : List<dynamic>.from(or!.map((x) => x)),
+        "and": List<dynamic>.from(and.map((x) => x)),
+        "or": List<dynamic>.from(or.map((x) => x)),
         "equal": equal,
         "field": field,
         "timeUnit": timeUnitValues.reverse[timeUnit],
-        "range": range == null ? null : List<dynamic>.from(range!.map((x) => x)),
-        "oneOf": oneOf == null ? null : List<dynamic>.from(oneOf!.map((x) => x)),
+        "range": List<dynamic>.from(range.map((x) => x)),
+        "oneOf": List<dynamic>.from(oneOf.map((x) => x)),
         "selection": selection,
     };
 }
@@ -5091,12 +5091,12 @@ class ConditionalPredicateMarkPropFieldDefClass {
     ///`"nominal"`).
     ///It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
     ///[geographic projection](projection.html) is applied.
-    final Type? type;
+    final Type type;
 
     ConditionalPredicateMarkPropFieldDefClass({
-        this.test,
-        this.value,
-        this.selection,
+        required this.test,
+        required this.value,
+        required this.selection,
         this.aggregate,
         this.bin,
         this.field,
@@ -5104,7 +5104,7 @@ class ConditionalPredicateMarkPropFieldDefClass {
         this.scale,
         this.sort,
         this.timeUnit,
-        this.type,
+        required this.type,
     });
 
     factory ConditionalPredicateMarkPropFieldDefClass.fromJson(Map<String, dynamic> json) => ConditionalPredicateMarkPropFieldDefClass(
@@ -5118,7 +5118,7 @@ class ConditionalPredicateMarkPropFieldDefClass {
         scale: json["scale"] == null ? null : Scale.fromJson(json["scale"]),
         sort: json["sort"],
         timeUnit: timeUnitValues.map[json["timeUnit"]],
-        type: typeValues.map[json["type"]],
+        type: typeValues.map[json["type"]]!,
     );
 
     Map<String, dynamic> toJson() => {
@@ -6063,7 +6063,7 @@ class DefWithCondition {
     ///`"nominal"`).
     ///It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
     ///[geographic projection](projection.html) is applied.
-    final Type? type;
+    final Type type;
     
     ///A constant value in visual domain.
     final dynamic value;
@@ -6074,7 +6074,7 @@ class DefWithCondition {
         this.condition,
         this.field,
         this.timeUnit,
-        this.type,
+        required this.type,
         this.value,
     });
 
@@ -6084,7 +6084,7 @@ class DefWithCondition {
         condition: json["condition"],
         field: json["field"],
         timeUnit: timeUnitValues.map[json["timeUnit"]],
-        type: typeValues.map[json["type"]],
+        type: typeValues.map[json["type"]]!,
         value: json["value"],
     );
 
@@ -6145,17 +6145,17 @@ class ConditionalPredicateFieldDefClass {
     ///`"nominal"`).
     ///It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
     ///[geographic projection](projection.html) is applied.
-    final Type? type;
+    final Type type;
 
     ConditionalPredicateFieldDefClass({
-        this.test,
-        this.value,
-        this.selection,
+        required this.test,
+        required this.value,
+        required this.selection,
         this.aggregate,
         this.bin,
         this.field,
         this.timeUnit,
-        this.type,
+        required this.type,
     });
 
     factory ConditionalPredicateFieldDefClass.fromJson(Map<String, dynamic> json) => ConditionalPredicateFieldDefClass(
@@ -6166,7 +6166,7 @@ class ConditionalPredicateFieldDefClass {
         bin: json["bin"],
         field: json["field"],
         timeUnit: timeUnitValues.map[json["timeUnit"]],
-        type: typeValues.map[json["type"]],
+        type: typeValues.map[json["type"]]!,
     );
 
     Map<String, dynamic> toJson() => {
@@ -6318,7 +6318,7 @@ class TextDefWithCondition {
     ///`"nominal"`).
     ///It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
     ///[geographic projection](projection.html) is applied.
-    final Type? type;
+    final Type type;
     
     ///A constant value in visual domain.
     final dynamic value;
@@ -6330,7 +6330,7 @@ class TextDefWithCondition {
         this.field,
         this.format,
         this.timeUnit,
-        this.type,
+        required this.type,
         this.value,
     });
 
@@ -6341,7 +6341,7 @@ class TextDefWithCondition {
         field: json["field"],
         format: json["format"],
         timeUnit: timeUnitValues.map[json["timeUnit"]],
-        type: typeValues.map[json["type"]],
+        type: typeValues.map[json["type"]]!,
         value: json["value"],
     );
 
@@ -6407,18 +6407,18 @@ class ConditionalPredicateTextFieldDefClass {
     ///`"nominal"`).
     ///It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
     ///[geographic projection](projection.html) is applied.
-    final Type? type;
+    final Type type;
 
     ConditionalPredicateTextFieldDefClass({
-        this.test,
-        this.value,
-        this.selection,
+        required this.test,
+        required this.value,
+        required this.selection,
         this.aggregate,
         this.bin,
         this.field,
         this.format,
         this.timeUnit,
-        this.type,
+        required this.type,
     });
 
     factory ConditionalPredicateTextFieldDefClass.fromJson(Map<String, dynamic> json) => ConditionalPredicateTextFieldDefClass(
@@ -6430,7 +6430,7 @@ class ConditionalPredicateTextFieldDefClass {
         field: json["field"],
         format: json["format"],
         timeUnit: timeUnitValues.map[json["timeUnit"]],
-        type: typeValues.map[json["type"]],
+        type: typeValues.map[json["type"]]!,
     );
 
     Map<String, dynamic> toJson() => {
@@ -6532,7 +6532,7 @@ class XClass {
     ///`"nominal"`).
     ///It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
     ///[geographic projection](projection.html) is applied.
-    final Type? type;
+    final Type type;
     
     ///A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
     ///`0` to `1` for opacity).
@@ -6547,8 +6547,8 @@ class XClass {
         this.sort,
         this.stack,
         this.timeUnit,
-        this.type,
-        this.value,
+        required this.type,
+        required this.value,
     });
 
     factory XClass.fromJson(Map<String, dynamic> json) => XClass(
@@ -6560,7 +6560,7 @@ class XClass {
         sort: json["sort"],
         stack: stackOffsetValues.map[json["stack"]],
         timeUnit: timeUnitValues.map[json["timeUnit"]],
-        type: typeValues.map[json["type"]],
+        type: typeValues.map[json["type"]]!,
         value: json["value"],
     );
 
@@ -6843,7 +6843,7 @@ class X2Class {
     ///`"nominal"`).
     ///It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
     ///[geographic projection](projection.html) is applied.
-    final Type? type;
+    final Type type;
     
     ///A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
     ///`0` to `1` for opacity).
@@ -6854,8 +6854,8 @@ class X2Class {
         this.bin,
         this.field,
         this.timeUnit,
-        this.type,
-        this.value,
+        required this.type,
+        required this.value,
     });
 
     factory X2Class.fromJson(Map<String, dynamic> json) => X2Class(
@@ -6863,7 +6863,7 @@ class X2Class {
         bin: json["bin"],
         field: json["field"],
         timeUnit: timeUnitValues.map[json["timeUnit"]],
-        type: typeValues.map[json["type"]],
+        type: typeValues.map[json["type"]]!,
         value: json["value"],
     );
 
@@ -6937,7 +6937,7 @@ class Spec {
     ///
     ///__Note__: Specifications inside `layer` cannot use `row` and `column` channels as
     ///layering facet specifications is not allowed.
-    final List<LayerSpec>? layer;
+    final List<LayerSpec> layer;
     
     ///Name of the visualization for later reference.
     final String? name;
@@ -6982,7 +6982,7 @@ class Spec {
     final double? width;
     
     ///A key-value mapping between encoding channels and definition of fields.
-    final Encoding? encoding;
+    final Encoding encoding;
     
     ///A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
     ///`"line"`,
@@ -7001,82 +7001,82 @@ class Spec {
     
     ///An object that describes mappings between `row` and `column` channels and their field
     ///definitions.
-    final FacetMapping? facet;
+    final FacetMapping facet;
     
     ///A specification of the view that gets faceted.
-    final Spec? spec;
+    final Spec spec;
     
     ///An object that describes what fields should be repeated into views that are laid out as a
     ///`row` or `column`.
-    final Repeat? repeat;
+    final Repeat repeat;
     
     ///A list of views that should be concatenated and put into a column.
-    final List<Spec>? vconcat;
+    final List<Spec> vconcat;
     
     ///A list of views that should be concatenated and put into a row.
-    final List<Spec>? hconcat;
+    final List<Spec> hconcat;
 
     Spec({
         this.data,
         this.description,
         this.height,
-        this.layer,
+        required this.layer,
         this.name,
         this.resolve,
         this.title,
         this.transform,
         this.width,
-        this.encoding,
-        this.mark,
+        required this.encoding,
+        required this.mark,
         this.projection,
         this.selection,
-        this.facet,
-        this.spec,
-        this.repeat,
-        this.vconcat,
-        this.hconcat,
+        required this.facet,
+        required this.spec,
+        required this.repeat,
+        required this.vconcat,
+        required this.hconcat,
     });
 
     factory Spec.fromJson(Map<String, dynamic> json) => Spec(
         data: json["data"] == null ? null : Data.fromJson(json["data"]),
         description: json["description"],
         height: json["height"]?.toDouble(),
-        layer: json["layer"] == null ? null : List<LayerSpec>.from(json["layer"]!.map((x) => LayerSpec.fromJson(x))),
+        layer: List<LayerSpec>.from(json["layer"].map((x) => LayerSpec.fromJson(x))),
         name: json["name"],
         resolve: json["resolve"] == null ? null : Resolve.fromJson(json["resolve"]),
         title: json["title"],
         transform: json["transform"] == null ? null : List<Transform>.from(json["transform"]!.map((x) => Transform.fromJson(x))),
         width: json["width"]?.toDouble(),
-        encoding: json["encoding"] == null ? null : Encoding.fromJson(json["encoding"]),
+        encoding: Encoding.fromJson(json["encoding"]),
         mark: json["mark"],
         projection: json["projection"] == null ? null : Projection.fromJson(json["projection"]),
         selection: Map.from(json["selection"]!).map((k, v) => MapEntry<String, SelectionDef>(k, SelectionDef.fromJson(v))),
-        facet: json["facet"] == null ? null : FacetMapping.fromJson(json["facet"]),
-        spec: json["spec"] == null ? null : Spec.fromJson(json["spec"]),
-        repeat: json["repeat"] == null ? null : Repeat.fromJson(json["repeat"]),
-        vconcat: json["vconcat"] == null ? null : List<Spec>.from(json["vconcat"]!.map((x) => Spec.fromJson(x))),
-        hconcat: json["hconcat"] == null ? null : List<Spec>.from(json["hconcat"]!.map((x) => Spec.fromJson(x))),
+        facet: FacetMapping.fromJson(json["facet"]),
+        spec: Spec.fromJson(json["spec"]),
+        repeat: Repeat.fromJson(json["repeat"]),
+        vconcat: List<Spec>.from(json["vconcat"].map((x) => Spec.fromJson(x))),
+        hconcat: List<Spec>.from(json["hconcat"].map((x) => Spec.fromJson(x))),
     );
 
     Map<String, dynamic> toJson() => {
         "data": data?.toJson(),
         "description": description,
         "height": height,
-        "layer": layer == null ? null : List<dynamic>.from(layer!.map((x) => x.toJson())),
+        "layer": List<dynamic>.from(layer.map((x) => x.toJson())),
         "name": name,
         "resolve": resolve?.toJson(),
         "title": title,
         "transform": transform == null ? null : List<dynamic>.from(transform!.map((x) => x.toJson())),
         "width": width,
-        "encoding": encoding?.toJson(),
+        "encoding": encoding.toJson(),
         "mark": mark,
         "projection": projection?.toJson(),
         "selection": Map.from(selection!).map((k, v) => MapEntry<String, dynamic>(k, v.toJson())),
-        "facet": facet?.toJson(),
-        "spec": spec?.toJson(),
-        "repeat": repeat?.toJson(),
-        "vconcat": vconcat == null ? null : List<dynamic>.from(vconcat!.map((x) => x.toJson())),
-        "hconcat": hconcat == null ? null : List<dynamic>.from(hconcat!.map((x) => x.toJson())),
+        "facet": facet.toJson(),
+        "spec": spec.toJson(),
+        "repeat": repeat.toJson(),
+        "vconcat": List<dynamic>.from(vconcat.map((x) => x.toJson())),
+        "hconcat": List<dynamic>.from(hconcat.map((x) => x.toJson())),
     };
 }
 
@@ -7231,7 +7231,7 @@ class LayerSpec {
     ///
     ///__Note__: Specifications inside `layer` cannot use `row` and `column` channels as
     ///layering facet specifications is not allowed.
-    final List<LayerSpec>? layer;
+    final List<LayerSpec> layer;
     
     ///Name of the visualization for later reference.
     final String? name;
@@ -7268,7 +7268,7 @@ class LayerSpec {
     final double? width;
     
     ///A key-value mapping between encoding channels and definition of fields.
-    final Encoding? encoding;
+    final Encoding encoding;
     
     ///A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
     ///`"line"`,
@@ -7289,14 +7289,14 @@ class LayerSpec {
         this.data,
         this.description,
         this.height,
-        this.layer,
+        required this.layer,
         this.name,
         this.resolve,
         this.title,
         this.transform,
         this.width,
-        this.encoding,
-        this.mark,
+        required this.encoding,
+        required this.mark,
         this.projection,
         this.selection,
     });
@@ -7305,13 +7305,13 @@ class LayerSpec {
         data: json["data"] == null ? null : Data.fromJson(json["data"]),
         description: json["description"],
         height: json["height"]?.toDouble(),
-        layer: json["layer"] == null ? null : List<LayerSpec>.from(json["layer"]!.map((x) => LayerSpec.fromJson(x))),
+        layer: List<LayerSpec>.from(json["layer"].map((x) => LayerSpec.fromJson(x))),
         name: json["name"],
         resolve: json["resolve"] == null ? null : Resolve.fromJson(json["resolve"]),
         title: json["title"],
         transform: json["transform"] == null ? null : List<Transform>.from(json["transform"]!.map((x) => Transform.fromJson(x))),
         width: json["width"]?.toDouble(),
-        encoding: json["encoding"] == null ? null : Encoding.fromJson(json["encoding"]),
+        encoding: Encoding.fromJson(json["encoding"]),
         mark: json["mark"],
         projection: json["projection"] == null ? null : Projection.fromJson(json["projection"]),
         selection: Map.from(json["selection"]!).map((k, v) => MapEntry<String, SelectionDef>(k, SelectionDef.fromJson(v))),
@@ -7321,13 +7321,13 @@ class LayerSpec {
         "data": data?.toJson(),
         "description": description,
         "height": height,
-        "layer": layer == null ? null : List<dynamic>.from(layer!.map((x) => x.toJson())),
+        "layer": List<dynamic>.from(layer.map((x) => x.toJson())),
         "name": name,
         "resolve": resolve?.toJson(),
         "title": title,
         "transform": transform == null ? null : List<dynamic>.from(transform!.map((x) => x.toJson())),
         "width": width,
-        "encoding": encoding?.toJson(),
+        "encoding": encoding.toJson(),
         "mark": mark,
         "projection": projection?.toJson(),
         "selection": Map.from(selection!).map((k, v) => MapEntry<String, dynamic>(k, v.toJson())),
@@ -8113,7 +8113,7 @@ class Transform {
     
     ///A [expression](types.html#expression) string. Use the variable `datum` to refer to the
     ///current data object.
-    final String? calculate;
+    final String calculate;
     
     ///The default value to use if lookup fails.
     ///
@@ -8121,10 +8121,10 @@ class Transform {
     final String? transformDefault;
     
     ///Secondary data reference.
-    final LookupData? from;
+    final LookupData from;
     
     ///Key in primary data source.
-    final String? lookup;
+    final String lookup;
     
     ///An object indicating bin properties, or simply `true` for using default bin parameters.
     final dynamic bin;
@@ -8132,29 +8132,29 @@ class Transform {
     ///The data field to bin.
     ///
     ///The data field to apply time unit.
-    final String? field;
+    final String field;
     
     ///The timeUnit.
-    final TimeUnit? timeUnit;
+    final TimeUnit timeUnit;
     
     ///Array of objects that define fields to aggregate.
-    final List<AggregatedFieldDef>? aggregate;
+    final List<AggregatedFieldDef> aggregate;
     
     ///The data fields to group by. If not specified, a single group containing all data objects
     ///will be used.
     final List<String>? groupby;
 
     Transform({
-        this.filter,
+        required this.filter,
         this.transformAs,
-        this.calculate,
+        required this.calculate,
         this.transformDefault,
-        this.from,
-        this.lookup,
-        this.bin,
-        this.field,
-        this.timeUnit,
-        this.aggregate,
+        required this.from,
+        required this.lookup,
+        required this.bin,
+        required this.field,
+        required this.timeUnit,
+        required this.aggregate,
         this.groupby,
     });
 
@@ -8163,12 +8163,12 @@ class Transform {
         transformAs: json["as"],
         calculate: json["calculate"],
         transformDefault: json["default"],
-        from: json["from"] == null ? null : LookupData.fromJson(json["from"]),
+        from: LookupData.fromJson(json["from"]),
         lookup: json["lookup"],
         bin: json["bin"],
         field: json["field"],
-        timeUnit: timeUnitValues.map[json["timeUnit"]],
-        aggregate: json["aggregate"] == null ? null : List<AggregatedFieldDef>.from(json["aggregate"]!.map((x) => AggregatedFieldDef.fromJson(x))),
+        timeUnit: timeUnitValues.map[json["timeUnit"]]!,
+        aggregate: List<AggregatedFieldDef>.from(json["aggregate"].map((x) => AggregatedFieldDef.fromJson(x))),
         groupby: json["groupby"] == null ? null : List<String>.from(json["groupby"]!.map((x) => x)),
     );
 
@@ -8177,12 +8177,12 @@ class Transform {
         "as": transformAs,
         "calculate": calculate,
         "default": transformDefault,
-        "from": from?.toJson(),
+        "from": from.toJson(),
         "lookup": lookup,
         "bin": bin,
         "field": field,
         "timeUnit": timeUnitValues.reverse[timeUnit],
-        "aggregate": aggregate == null ? null : List<dynamic>.from(aggregate!.map((x) => x.toJson())),
+        "aggregate": List<dynamic>.from(aggregate.map((x) => x.toJson())),
         "groupby": groupby == null ? null : List<dynamic>.from(groupby!.map((x) => x)),
     };
 }
diff --git a/base/schema-elixir/test/inputs/schema/vega-lite.schema/default/QuickType.ex b/head/schema-elixir/test/inputs/schema/vega-lite.schema/default/QuickType.ex
index 0e82e11..1b4f025 100644
--- a/base/schema-elixir/test/inputs/schema/vega-lite.schema/default/QuickType.ex
+++ b/head/schema-elixir/test/inputs/schema/vega-lite.schema/default/QuickType.ex
@@ -1938,12 +1938,13 @@ defmodule ProjectionConfig do
 end
 
 defmodule VGScheme do
+  @enforce_keys [:scheme]
   defstruct [:count, :extent, :scheme, :step]
 
   @type t :: %__MODULE__{
           count: float() | nil,
           extent: [float()] | nil,
-          scheme: String.t() | nil,
+          scheme: String.t(),
           step: float() | nil
         }
 
@@ -2502,13 +2503,13 @@ defmodule MultiSelectionConfig do
 end
 
 defmodule VGBinding do
-  @enforce_keys [:input]
+  @enforce_keys [:input, :options]
   defstruct [:element, :input, :options, :max, :min, :step]
 
   @type t :: %__MODULE__{
           element: String.t() | nil,
           input: String.t(),
-          options: [String.t()] | nil,
+          options: [String.t()],
           max: float() | nil,
           min: float() | nil,
           step: float() | nil
@@ -3596,7 +3597,7 @@ defmodule ConfigClass do
   def encode_padding(value) when is_nil(value), do: value
   def encode_padding(_), do: {:error, "Unexpected type when encoding ConfigClass.padding"}
 
-  def decode_range_value(%{} = value), do: VGScheme.from_map(value)
+  def decode_range_value(%{"scheme" => _,} = value), do: VGScheme.from_map(value)
   def decode_range_value(value) when is_list(value), do: value
   def decode_range_value(_), do: {:error, "Unexpected type when decoding ConfigClass.range"}
 
@@ -3881,25 +3882,24 @@ defmodule Data do
   - `:name` - Provide a placeholder name and bind data at runtime.
   """
 
+  @enforce_keys [:url, :values, :name]
   defstruct [:format, :url, :values, :name]
 
   @type t :: %__MODULE__{
           format: DataFormat.t() | nil,
-          url: String.t() | nil,
-          values: [boolean() | float() | %{String.t() => any()} | String.t()] | %{String.t() => any()} | String.t() | nil,
-          name: String.t() | nil
+          url: String.t(),
+          values: [boolean() | float() | %{String.t() => any()} | String.t()] | %{String.t() => any()} | String.t(),
+          name: String.t()
         }
 
   def decode_values(value) when is_binary(value), do: value
   def decode_values(value) when is_list(value), do: value
   def decode_values(value) when is_map(value), do: value
-  def decode_values(value) when is_nil(value), do: value
   def decode_values(_), do: {:error, "Unexpected type when decoding Data.values"}
 
   def encode_values(value) when is_binary(value), do: value
   def encode_values(value) when is_list(value), do: value
   def encode_values(value) when is_map(value), do: value
-  def encode_values(value) when is_nil(value), do: value
   def encode_values(_), do: {:error, "Unexpected type when encoding Data.values"}
 
   def from_map(m) do
@@ -4084,25 +4084,24 @@ defmodule BinParams do
 end
 
 defmodule Selection do
+  @enforce_keys [:selection_not, :selection_and, :selection_or]
   defstruct [:selection_not, :selection_and, :selection_or]
 
   @type t :: %__MODULE__{
-          selection_not: Selection.t() | String.t() | nil,
-          selection_and: [Selection.t() | String.t()] | nil,
-          selection_or: [Selection.t() | String.t()] | nil
+          selection_not: Selection.t() | String.t(),
+          selection_and: [Selection.t() | String.t()],
+          selection_or: [Selection.t() | String.t()]
         }
 
-  def decode_selection_not(%{} = value), do: Selection.from_map(value)
+  def decode_selection_not(%{"not" => _,"and" => _,"or" => _,} = value), do: Selection.from_map(value)
   def decode_selection_not(value) when is_binary(value), do: value
-  def decode_selection_not(value) when is_nil(value), do: value
   def decode_selection_not(_), do: {:error, "Unexpected type when decoding Selection.selection_not"}
 
   def encode_selection_not(%Selection{} = value), do: Selection.to_map(value)
   def encode_selection_not(value) when is_binary(value), do: value
-  def encode_selection_not(value) when is_nil(value), do: value
   def encode_selection_not(_), do: {:error, "Unexpected type when encoding Selection.selection_not"}
 
-  def decode_selection_and_element(%{} = value), do: Selection.from_map(value)
+  def decode_selection_and_element(%{"not" => _,"and" => _,"or" => _,} = value), do: Selection.from_map(value)
   def decode_selection_and_element(value) when is_binary(value), do: value
   def decode_selection_and_element(_), do: {:error, "Unexpected type when decoding Selection.selection_and"}
 
@@ -4110,7 +4109,7 @@ defmodule Selection do
   def encode_selection_and_element(value) when is_binary(value), do: value
   def encode_selection_and_element(_), do: {:error, "Unexpected type when encoding Selection.selection_and"}
 
-  def decode_selection_or_element(%{} = value), do: Selection.from_map(value)
+  def decode_selection_or_element(%{"not" => _,"and" => _,"or" => _,} = value), do: Selection.from_map(value)
   def decode_selection_or_element(value) when is_binary(value), do: value
   def decode_selection_or_element(_), do: {:error, "Unexpected type when decoding Selection.selection_or"}
 
@@ -4121,8 +4120,8 @@ defmodule Selection do
   def from_map(m) do
     %Selection{
       selection_not: decode_selection_not(m["not"]),
-      selection_and: m["and"] && Enum.map(m["and"], &decode_selection_and_element/1),
-      selection_or: m["or"] && Enum.map(m["or"], &decode_selection_or_element/1),
+      selection_and: Enum.map(m["and"], &decode_selection_and_element/1),
+      selection_or: Enum.map(m["or"], &decode_selection_or_element/1),
     }
   end
 
@@ -4333,31 +4332,30 @@ defmodule Predicate do
   - `:selection` - Filter using a selection name.
   """
 
+  @enforce_keys [:predicate_not, :predicate_and, :predicate_or, :equal, :field, :range, :one_of, :selection]
   defstruct [:predicate_not, :predicate_and, :predicate_or, :equal, :field, :time_unit, :range, :one_of, :selection]
 
   @type t :: %__MODULE__{
-          predicate_not: Predicate.t() | String.t() | nil,
-          predicate_and: [Predicate.t() | String.t()] | nil,
-          predicate_or: [Predicate.t() | String.t()] | nil,
-          equal: boolean() | DateTimeClass.t() | float() | String.t() | nil,
-          field: String.t() | nil,
+          predicate_not: Predicate.t() | String.t(),
+          predicate_and: [Predicate.t() | String.t()],
+          predicate_or: [Predicate.t() | String.t()],
+          equal: boolean() | DateTimeClass.t() | float() | String.t(),
+          field: String.t(),
           time_unit: TimeUnit.t() | nil,
-          range: [DateTimeClass.t() | float() | nil] | nil,
-          one_of: [boolean() | DateTimeClass.t() | float() | String.t()] | nil,
-          selection: Selection.t() | String.t() | nil
+          range: [DateTimeClass.t() | float() | nil],
+          one_of: [boolean() | DateTimeClass.t() | float() | String.t()],
+          selection: Selection.t() | String.t()
         }
 
-  def decode_predicate_not(%{} = value), do: Predicate.from_map(value)
+  def decode_predicate_not(%{"not" => _,"and" => _,"or" => _,"equal" => _,"field" => _,"range" => _,"oneOf" => _,"selection" => _,} = value), do: Predicate.from_map(value)
   def decode_predicate_not(value) when is_binary(value), do: value
-  def decode_predicate_not(value) when is_nil(value), do: value
   def decode_predicate_not(_), do: {:error, "Unexpected type when decoding Predicate.predicate_not"}
 
   def encode_predicate_not(%Predicate{} = value), do: Predicate.to_map(value)
   def encode_predicate_not(value) when is_binary(value), do: value
-  def encode_predicate_not(value) when is_nil(value), do: value
   def encode_predicate_not(_), do: {:error, "Unexpected type when encoding Predicate.predicate_not"}
 
-  def decode_predicate_and_element(%{} = value), do: Predicate.from_map(value)
+  def decode_predicate_and_element(%{"not" => _,"and" => _,"or" => _,"equal" => _,"field" => _,"range" => _,"oneOf" => _,"selection" => _,} = value), do: Predicate.from_map(value)
   def decode_predicate_and_element(value) when is_binary(value), do: value
   def decode_predicate_and_element(_), do: {:error, "Unexpected type when decoding Predicate.predicate_and"}
 
@@ -4365,7 +4363,7 @@ defmodule Predicate do
   def encode_predicate_and_element(value) when is_binary(value), do: value
   def encode_predicate_and_element(_), do: {:error, "Unexpected type when encoding Predicate.predicate_and"}
 
-  def decode_predicate_or_element(%{} = value), do: Predicate.from_map(value)
+  def decode_predicate_or_element(%{"not" => _,"and" => _,"or" => _,"equal" => _,"field" => _,"range" => _,"oneOf" => _,"selection" => _,} = value), do: Predicate.from_map(value)
   def decode_predicate_or_element(value) when is_binary(value), do: value
   def decode_predicate_or_element(_), do: {:error, "Unexpected type when decoding Predicate.predicate_or"}
 
@@ -4378,7 +4376,6 @@ defmodule Predicate do
   def decode_equal(value) when is_float(value), do: value
   def decode_equal(value) when is_integer(value), do: value
   def decode_equal(value) when is_binary(value), do: value
-  def decode_equal(value) when is_nil(value), do: value
   def decode_equal(_), do: {:error, "Unexpected type when decoding Predicate.equal"}
 
   def encode_equal(%DateTimeClass{} = value), do: DateTimeClass.to_map(value)
@@ -4386,7 +4383,6 @@ defmodule Predicate do
   def encode_equal(value) when is_float(value), do: value
   def encode_equal(value) when is_integer(value), do: value
   def encode_equal(value) when is_binary(value), do: value
-  def encode_equal(value) when is_nil(value), do: value
   def encode_equal(_), do: {:error, "Unexpected type when encoding Predicate.equal"}
 
   def decode_range_element(%{} = value), do: DateTimeClass.from_map(value)
@@ -4415,26 +4411,24 @@ defmodule Predicate do
   def encode_one_of_element(value) when is_binary(value), do: value
   def encode_one_of_element(_), do: {:error, "Unexpected type when encoding Predicate.one_of"}
 
-  def decode_selection(%{} = value), do: Selection.from_map(value)
+  def decode_selection(%{"not" => _,"and" => _,"or" => _,} = value), do: Selection.from_map(value)
   def decode_selection(value) when is_binary(value), do: value
-  def decode_selection(value) when is_nil(value), do: value
   def decode_selection(_), do: {:error, "Unexpected type when decoding Predicate.selection"}
 
   def encode_selection(%Selection{} = value), do: Selection.to_map(value)
   def encode_selection(value) when is_binary(value), do: value
-  def encode_selection(value) when is_nil(value), do: value
   def encode_selection(_), do: {:error, "Unexpected type when encoding Predicate.selection"}
 
   def from_map(m) do
     %Predicate{
       predicate_not: decode_predicate_not(m["not"]),
-      predicate_and: m["and"] && Enum.map(m["and"], &decode_predicate_and_element/1),
-      predicate_or: m["or"] && Enum.map(m["or"], &decode_predicate_or_element/1),
+      predicate_and: Enum.map(m["and"], &decode_predicate_and_element/1),
+      predicate_or: Enum.map(m["or"], &decode_predicate_or_element/1),
       equal: decode_equal(m["equal"]),
       field: m["field"],
       time_unit: m["timeUnit"] && TimeUnit.decode(m["timeUnit"]),
-      range: m["range"] && Enum.map(m["range"], &decode_range_element/1),
-      one_of: m["oneOf"] && Enum.map(m["oneOf"], &decode_one_of_element/1),
+      range: Enum.map(m["range"], &decode_range_element/1),
+      one_of: Enum.map(m["oneOf"], &decode_one_of_element/1),
       selection: decode_selection(m["selection"]),
     }
   end
@@ -4472,33 +4466,29 @@ defmodule ConditionalValueDef do
   - `:selection` - A [selection name](selection.html), or a series of [composedselections](selection.html#compose).
   """
 
-  @enforce_keys [:value]
+  @enforce_keys [:test, :value, :selection]
   defstruct [:test, :value, :selection]
 
   @type t :: %__MODULE__{
-          test: Predicate.t() | String.t() | nil,
+          test: Predicate.t() | String.t(),
           value: boolean() | float() | String.t(),
-          selection: Selection.t() | String.t() | nil
+          selection: Selection.t() | String.t()
         }
 
-  def decode_test(%{} = value), do: Predicate.from_map(value)
+  def decode_test(%{"not" => _,"and" => _,"or" => _,"equal" => _,"field" => _,"range" => _,"oneOf" => _,"selection" => _,} = value), do: Predicate.from_map(value)
   def decode_test(value) when is_binary(value), do: value
-  def decode_test(value) when is_nil(value), do: value
   def decode_test(_), do: {:error, "Unexpected type when decoding ConditionalValueDef.test"}
 
   def encode_test(%Predicate{} = value), do: Predicate.to_map(value)
   def encode_test(value) when is_binary(value), do: value
-  def encode_test(value) when is_nil(value), do: value
   def encode_test(_), do: {:error, "Unexpected type when encoding ConditionalValueDef.test"}
 
-  def decode_selection(%{} = value), do: Selection.from_map(value)
+  def decode_selection(%{"not" => _,"and" => _,"or" => _,} = value), do: Selection.from_map(value)
   def decode_selection(value) when is_binary(value), do: value
-  def decode_selection(value) when is_nil(value), do: value
   def decode_selection(_), do: {:error, "Unexpected type when decoding ConditionalValueDef.selection"}
 
   def encode_selection(%Selection{} = value), do: Selection.to_map(value)
   def encode_selection(value) when is_binary(value), do: value
-  def encode_selection(value) when is_nil(value), do: value
   def encode_selection(_), do: {:error, "Unexpected type when encoding ConditionalValueDef.selection"}
 
   def from_map(m) do
@@ -5456,12 +5446,13 @@ defmodule ConditionalPredicateMarkPropFieldDefClass do
   - `:type` - The encoded field's type of measurement (`"quantitative"`, `"temporal"`, `"ordinal"`, or`"nominal"`).It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a[geographic projection](projection.html) is applied.
   """
 
+  @enforce_keys [:test, :value, :selection, :type]
   defstruct [:test, :value, :selection, :aggregate, :bin, :field, :legend, :scale, :sort, :time_unit, :type]
 
   @type t :: %__MODULE__{
-          test: Predicate.t() | String.t() | nil,
-          value: boolean() | float() | String.t() | nil,
-          selection: Selection.t() | String.t() | nil,
+          test: Predicate.t() | String.t(),
+          value: boolean() | float() | String.t(),
+          selection: Selection.t() | String.t(),
           aggregate: AggregateOp.t() | nil,
           bin: boolean() | BinParams.t() | nil,
           field: RepeatRef.t() | String.t() | nil,
@@ -5469,27 +5460,23 @@ defmodule ConditionalPredicateMarkPropFieldDefClass do
           scale: Scale.t() | nil,
           sort: SortField.t() | SortEnum.t() | nil | nil,
           time_unit: TimeUnit.t() | nil,
-          type: Type.t() | nil
+          type: Type.t()
         }
 
-  def decode_test(%{} = value), do: Predicate.from_map(value)
+  def decode_test(%{"not" => _,"and" => _,"or" => _,"equal" => _,"field" => _,"range" => _,"oneOf" => _,"selection" => _,} = value), do: Predicate.from_map(value)
   def decode_test(value) when is_binary(value), do: value
-  def decode_test(value) when is_nil(value), do: value
   def decode_test(_), do: {:error, "Unexpected type when decoding ConditionalPredicateMarkPropFieldDefClass.test"}
 
   def encode_test(%Predicate{} = value), do: Predicate.to_map(value)
   def encode_test(value) when is_binary(value), do: value
-  def encode_test(value) when is_nil(value), do: value
   def encode_test(_), do: {:error, "Unexpected type when encoding ConditionalPredicateMarkPropFieldDefClass.test"}
 
-  def decode_selection(%{} = value), do: Selection.from_map(value)
+  def decode_selection(%{"not" => _,"and" => _,"or" => _,} = value), do: Selection.from_map(value)
   def decode_selection(value) when is_binary(value), do: value
-  def decode_selection(value) when is_nil(value), do: value
   def decode_selection(_), do: {:error, "Unexpected type when decoding ConditionalPredicateMarkPropFieldDefClass.selection"}
 
   def encode_selection(%Selection{} = value), do: Selection.to_map(value)
   def encode_selection(value) when is_binary(value), do: value
-  def encode_selection(value) when is_nil(value), do: value
   def encode_selection(_), do: {:error, "Unexpected type when encoding ConditionalPredicateMarkPropFieldDefClass.selection"}
 
   def decode_bin(%{} = value), do: BinParams.from_map(value)
@@ -5534,7 +5521,7 @@ defmodule ConditionalPredicateMarkPropFieldDefClass do
       scale: m["scale"] && Scale.from_map(m["scale"]),
       sort: decode_sort(m["sort"]),
       time_unit: m["timeUnit"] && TimeUnit.decode(m["timeUnit"]),
-      type: m["type"] && Type.decode(m["type"]),
+      type: Type.decode(m["type"]),
     }
   end
 
@@ -5556,7 +5543,7 @@ defmodule ConditionalPredicateMarkPropFieldDefClass do
       "scale" => struct.scale && Scale.to_map(struct.scale),
       "sort" => encode_sort(struct.sort),
       "timeUnit" => struct.time_unit && TimeUnit.encode(struct.time_unit),
-      "type" => struct.type && Type.encode(struct.type),
+      "type" => Type.encode(struct.type),
     }
   end
 
@@ -5622,6 +5609,7 @@ defmodule MarkPropDefWithCondition do
   - `:value` - A constant value in visual domain.
   """
 
+  @enforce_keys [:type]
   defstruct [:aggregate, :bin, :condition, :field, :legend, :scale, :sort, :time_unit, :type, :value]
 
   @type t :: %__MODULE__{
@@ -5633,7 +5621,7 @@ defmodule MarkPropDefWithCondition do
           scale: Scale.t() | nil,
           sort: SortField.t() | SortEnum.t() | nil | nil,
           time_unit: TimeUnit.t() | nil,
-          type: Type.t() | nil,
+          type: Type.t(),
           value: boolean() | float() | String.t() | nil
         }
 
@@ -5647,7 +5635,7 @@ defmodule MarkPropDefWithCondition do
   def encode_bin(value) when is_nil(value), do: value
   def encode_bin(_), do: {:error, "Unexpected type when encoding MarkPropDefWithCondition.bin"}
 
-  def decode_condition(%{} = value), do: ConditionalPredicateMarkPropFieldDefClass.from_map(value)
+  def decode_condition(%{"test" => _,"value" => _,"selection" => _,"type" => _,} = value), do: ConditionalPredicateMarkPropFieldDefClass.from_map(value)
   def decode_condition(value) when is_list(value), do: value
   def decode_condition(value) when is_nil(value), do: value
   def decode_condition(_), do: {:error, "Unexpected type when decoding MarkPropDefWithCondition.condition"}
@@ -5687,7 +5675,7 @@ defmodule MarkPropDefWithCondition do
       scale: m["scale"] && Scale.from_map(m["scale"]),
       sort: decode_sort(m["sort"]),
       time_unit: m["timeUnit"] && TimeUnit.decode(m["timeUnit"]),
-      type: m["type"] && Type.decode(m["type"]),
+      type: Type.decode(m["type"]),
       value: m["value"],
     }
   end
@@ -5708,7 +5696,7 @@ defmodule MarkPropDefWithCondition do
       "scale" => struct.scale && Scale.to_map(struct.scale),
       "sort" => encode_sort(struct.sort),
       "timeUnit" => struct.time_unit && TimeUnit.encode(struct.time_unit),
-      "type" => struct.type && Type.encode(struct.type),
+      "type" => Type.encode(struct.type),
       "value" => struct.value,
     }
   end
@@ -5936,37 +5924,34 @@ defmodule ConditionalPredicateFieldDefClass do
   - `:type` - The encoded field's type of measurement (`"quantitative"`, `"temporal"`, `"ordinal"`, or`"nominal"`).It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a[geographic projection](projection.html) is applied.
   """
 
+  @enforce_keys [:test, :value, :selection, :type]
   defstruct [:test, :value, :selection, :aggregate, :bin, :field, :time_unit, :type]
 
   @type t :: %__MODULE__{
-          test: Predicate.t() | String.t() | nil,
-          value: boolean() | float() | String.t() | nil,
-          selection: Selection.t() | String.t() | nil,
+          test: Predicate.t() | String.t(),
+          value: boolean() | float() | String.t(),
+          selection: Selection.t() | String.t(),
           aggregate: AggregateOp.t() | nil,
           bin: boolean() | BinParams.t() | nil,
           field: RepeatRef.t() | String.t() | nil,
           time_unit: TimeUnit.t() | nil,
-          type: Type.t() | nil
+          type: Type.t()
         }
 
-  def decode_test(%{} = value), do: Predicate.from_map(value)
+  def decode_test(%{"not" => _,"and" => _,"or" => _,"equal" => _,"field" => _,"range" => _,"oneOf" => _,"selection" => _,} = value), do: Predicate.from_map(value)
   def decode_test(value) when is_binary(value), do: value
-  def decode_test(value) when is_nil(value), do: value
   def decode_test(_), do: {:error, "Unexpected type when decoding ConditionalPredicateFieldDefClass.test"}
 
   def encode_test(%Predicate{} = value), do: Predicate.to_map(value)
   def encode_test(value) when is_binary(value), do: value
-  def encode_test(value) when is_nil(value), do: value
   def encode_test(_), do: {:error, "Unexpected type when encoding ConditionalPredicateFieldDefClass.test"}
 
-  def decode_selection(%{} = value), do: Selection.from_map(value)
+  def decode_selection(%{"not" => _,"and" => _,"or" => _,} = value), do: Selection.from_map(value)
   def decode_selection(value) when is_binary(value), do: value
-  def decode_selection(value) when is_nil(value), do: value
   def decode_selection(_), do: {:error, "Unexpected type when decoding ConditionalPredicateFieldDefClass.selection"}
 
   def encode_selection(%Selection{} = value), do: Selection.to_map(value)
   def encode_selection(value) when is_binary(value), do: value
-  def encode_selection(value) when is_nil(value), do: value
   def encode_selection(_), do: {:error, "Unexpected type when encoding ConditionalPredicateFieldDefClass.selection"}
 
   def decode_bin(%{} = value), do: BinParams.from_map(value)
@@ -5998,7 +5983,7 @@ defmodule ConditionalPredicateFieldDefClass do
       bin: decode_bin(m["bin"]),
       field: decode_field(m["field"]),
       time_unit: m["timeUnit"] && TimeUnit.decode(m["timeUnit"]),
-      type: m["type"] && Type.decode(m["type"]),
+      type: Type.decode(m["type"]),
     }
   end
 
@@ -6017,7 +6002,7 @@ defmodule ConditionalPredicateFieldDefClass do
       "bin" => encode_bin(struct.bin),
       "field" => encode_field(struct.field),
       "timeUnit" => struct.time_unit && TimeUnit.encode(struct.time_unit),
-      "type" => struct.type && Type.encode(struct.type),
+      "type" => Type.encode(struct.type),
     }
   end
 
@@ -6053,6 +6038,7 @@ defmodule DefWithCondition do
   - `:value` - A constant value in visual domain.
   """
 
+  @enforce_keys [:type]
   defstruct [:aggregate, :bin, :condition, :field, :time_unit, :type, :value]
 
   @type t :: %__MODULE__{
@@ -6061,7 +6047,7 @@ defmodule DefWithCondition do
           condition: [ConditionalValueDef.t()] | ConditionalPredicateFieldDefClass.t() | nil,
           field: RepeatRef.t() | String.t() | nil,
           time_unit: TimeUnit.t() | nil,
-          type: Type.t() | nil,
+          type: Type.t(),
           value: boolean() | float() | String.t() | nil
         }
 
@@ -6075,7 +6061,7 @@ defmodule DefWithCondition do
   def encode_bin(value) when is_nil(value), do: value
   def encode_bin(_), do: {:error, "Unexpected type when encoding DefWithCondition.bin"}
 
-  def decode_condition(%{} = value), do: ConditionalPredicateFieldDefClass.from_map(value)
+  def decode_condition(%{"test" => _,"value" => _,"selection" => _,"type" => _,} = value), do: ConditionalPredicateFieldDefClass.from_map(value)
   def decode_condition(value) when is_list(value), do: value
   def decode_condition(value) when is_nil(value), do: value
   def decode_condition(_), do: {:error, "Unexpected type when decoding DefWithCondition.condition"}
@@ -6102,7 +6088,7 @@ defmodule DefWithCondition do
       condition: decode_condition(m["condition"]),
       field: decode_field(m["field"]),
       time_unit: m["timeUnit"] && TimeUnit.decode(m["timeUnit"]),
-      type: m["type"] && Type.decode(m["type"]),
+      type: Type.decode(m["type"]),
       value: m["value"],
     }
   end
@@ -6120,7 +6106,7 @@ defmodule DefWithCondition do
       "condition" => encode_condition(struct.condition),
       "field" => encode_field(struct.field),
       "timeUnit" => struct.time_unit && TimeUnit.encode(struct.time_unit),
-      "type" => struct.type && Type.encode(struct.type),
+      "type" => Type.encode(struct.type),
       "value" => struct.value,
     }
   end
@@ -6221,38 +6207,35 @@ defmodule ConditionalPredicateTextFieldDefClass do
   - `:type` - The encoded field's type of measurement (`"quantitative"`, `"temporal"`, `"ordinal"`, or`"nominal"`).It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a[geographic projection](projection.html) is applied.
   """
 
+  @enforce_keys [:test, :value, :selection, :type]
   defstruct [:test, :value, :selection, :aggregate, :bin, :field, :format, :time_unit, :type]
 
   @type t :: %__MODULE__{
-          test: Predicate.t() | String.t() | nil,
-          value: boolean() | float() | String.t() | nil,
-          selection: Selection.t() | String.t() | nil,
+          test: Predicate.t() | String.t(),
+          value: boolean() | float() | String.t(),
+          selection: Selection.t() | String.t(),
           aggregate: AggregateOp.t() | nil,
           bin: boolean() | BinParams.t() | nil,
           field: RepeatRef.t() | String.t() | nil,
           format: String.t() | nil,
           time_unit: TimeUnit.t() | nil,
-          type: Type.t() | nil
+          type: Type.t()
         }
 
-  def decode_test(%{} = value), do: Predicate.from_map(value)
+  def decode_test(%{"not" => _,"and" => _,"or" => _,"equal" => _,"field" => _,"range" => _,"oneOf" => _,"selection" => _,} = value), do: Predicate.from_map(value)
   def decode_test(value) when is_binary(value), do: value
-  def decode_test(value) when is_nil(value), do: value
   def decode_test(_), do: {:error, "Unexpected type when decoding ConditionalPredicateTextFieldDefClass.test"}
 
   def encode_test(%Predicate{} = value), do: Predicate.to_map(value)
   def encode_test(value) when is_binary(value), do: value
-  def encode_test(value) when is_nil(value), do: value
   def encode_test(_), do: {:error, "Unexpected type when encoding ConditionalPredicateTextFieldDefClass.test"}
 
-  def decode_selection(%{} = value), do: Selection.from_map(value)
+  def decode_selection(%{"not" => _,"and" => _,"or" => _,} = value), do: Selection.from_map(value)
   def decode_selection(value) when is_binary(value), do: value
-  def decode_selection(value) when is_nil(value), do: value
   def decode_selection(_), do: {:error, "Unexpected type when decoding ConditionalPredicateTextFieldDefClass.selection"}
 
   def encode_selection(%Selection{} = value), do: Selection.to_map(value)
   def encode_selection(value) when is_binary(value), do: value
-  def encode_selection(value) when is_nil(value), do: value
   def encode_selection(_), do: {:error, "Unexpected type when encoding ConditionalPredicateTextFieldDefClass.selection"}
 
   def decode_bin(%{} = value), do: BinParams.from_map(value)
@@ -6285,7 +6268,7 @@ defmodule ConditionalPredicateTextFieldDefClass do
       field: decode_field(m["field"]),
       format: m["format"],
       time_unit: m["timeUnit"] && TimeUnit.decode(m["timeUnit"]),
-      type: m["type"] && Type.decode(m["type"]),
+      type: Type.decode(m["type"]),
     }
   end
 
@@ -6305,7 +6288,7 @@ defmodule ConditionalPredicateTextFieldDefClass do
       "field" => encode_field(struct.field),
       "format" => struct.format,
       "timeUnit" => struct.time_unit && TimeUnit.encode(struct.time_unit),
-      "type" => struct.type && Type.encode(struct.type),
+      "type" => Type.encode(struct.type),
     }
   end
 
@@ -6344,6 +6327,7 @@ defmodule TextDefWithCondition do
   - `:value` - A constant value in visual domain.
   """
 
+  @enforce_keys [:type]
   defstruct [:aggregate, :bin, :condition, :field, :format, :time_unit, :type, :value]
 
   @type t :: %__MODULE__{
@@ -6353,7 +6337,7 @@ defmodule TextDefWithCondition do
           field: RepeatRef.t() | String.t() | nil,
           format: String.t() | nil,
           time_unit: TimeUnit.t() | nil,
-          type: Type.t() | nil,
+          type: Type.t(),
           value: boolean() | float() | String.t() | nil
         }
 
@@ -6367,7 +6351,7 @@ defmodule TextDefWithCondition do
   def encode_bin(value) when is_nil(value), do: value
   def encode_bin(_), do: {:error, "Unexpected type when encoding TextDefWithCondition.bin"}
 
-  def decode_condition(%{} = value), do: ConditionalPredicateTextFieldDefClass.from_map(value)
+  def decode_condition(%{"test" => _,"value" => _,"selection" => _,"type" => _,} = value), do: ConditionalPredicateTextFieldDefClass.from_map(value)
   def decode_condition(value) when is_list(value), do: value
   def decode_condition(value) when is_nil(value), do: value
   def decode_condition(_), do: {:error, "Unexpected type when decoding TextDefWithCondition.condition"}
@@ -6395,7 +6379,7 @@ defmodule TextDefWithCondition do
       field: decode_field(m["field"]),
       format: m["format"],
       time_unit: m["timeUnit"] && TimeUnit.decode(m["timeUnit"]),
-      type: m["type"] && Type.decode(m["type"]),
+      type: Type.decode(m["type"]),
       value: m["value"],
     }
   end
@@ -6414,7 +6398,7 @@ defmodule TextDefWithCondition do
       "field" => encode_field(struct.field),
       "format" => struct.format,
       "timeUnit" => struct.time_unit && TimeUnit.encode(struct.time_unit),
-      "type" => struct.type && Type.encode(struct.type),
+      "type" => Type.encode(struct.type),
       "value" => struct.value,
     }
   end
@@ -6585,6 +6569,7 @@ defmodule XClass do
   - `:value` - A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between`0` to `1` for opacity).
   """
 
+  @enforce_keys [:type, :value]
   defstruct [:aggregate, :axis, :bin, :field, :scale, :sort, :stack, :time_unit, :type, :value]
 
   @type t :: %__MODULE__{
@@ -6596,8 +6581,8 @@ defmodule XClass do
           sort: SortField.t() | SortEnum.t() | nil | nil,
           stack: StackOffset.t() | nil | nil,
           time_unit: TimeUnit.t() | nil,
-          type: Type.t() | nil,
-          value: boolean() | float() | String.t() | nil
+          type: Type.t(),
+          value: boolean() | float() | String.t()
         }
 
   def decode_bin(%{} = value), do: BinParams.from_map(value)
@@ -6640,7 +6625,7 @@ defmodule XClass do
       sort: decode_sort(m["sort"]),
       stack: m["stack"] && StackOffset.decode(m["stack"]),
       time_unit: m["timeUnit"] && TimeUnit.decode(m["timeUnit"]),
-      type: m["type"] && Type.decode(m["type"]),
+      type: Type.decode(m["type"]),
       value: m["value"],
     }
   end
@@ -6661,7 +6646,7 @@ defmodule XClass do
       "sort" => encode_sort(struct.sort),
       "stack" => struct.stack && StackOffset.encode(struct.stack),
       "timeUnit" => struct.time_unit && TimeUnit.encode(struct.time_unit),
-      "type" => struct.type && Type.encode(struct.type),
+      "type" => Type.encode(struct.type),
       "value" => struct.value,
     }
   end
@@ -6690,6 +6675,7 @@ defmodule X2Class do
   - `:value` - A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between`0` to `1` for opacity).
   """
 
+  @enforce_keys [:type, :value]
   defstruct [:aggregate, :bin, :field, :time_unit, :type, :value]
 
   @type t :: %__MODULE__{
@@ -6697,8 +6683,8 @@ defmodule X2Class do
           bin: boolean() | BinParams.t() | nil,
           field: RepeatRef.t() | String.t() | nil,
           time_unit: TimeUnit.t() | nil,
-          type: Type.t() | nil,
-          value: boolean() | float() | String.t() | nil
+          type: Type.t(),
+          value: boolean() | float() | String.t()
         }
 
   def decode_bin(%{} = value), do: BinParams.from_map(value)
@@ -6727,7 +6713,7 @@ defmodule X2Class do
       bin: decode_bin(m["bin"]),
       field: decode_field(m["field"]),
       time_unit: m["timeUnit"] && TimeUnit.decode(m["timeUnit"]),
-      type: m["type"] && Type.decode(m["type"]),
+      type: Type.decode(m["type"]),
       value: m["value"],
     }
   end
@@ -6744,7 +6730,7 @@ defmodule X2Class do
       "bin" => encode_bin(struct.bin),
       "field" => encode_field(struct.field),
       "timeUnit" => struct.time_unit && TimeUnit.encode(struct.time_unit),
-      "type" => struct.type && Type.encode(struct.type),
+      "type" => Type.encode(struct.type),
       "value" => struct.value,
     }
   end
@@ -7890,30 +7876,29 @@ defmodule Transform do
   - `:groupby` - The data fields to group by. If not specified, a single group containing all data objectswill be used.
   """
 
+  @enforce_keys [:filter, :calculate, :from, :lookup, :bin, :field, :time_unit, :aggregate]
   defstruct [:filter, :as, :calculate, :default, :from, :lookup, :bin, :field, :time_unit, :aggregate, :groupby]
 
   @type t :: %__MODULE__{
-          filter: Predicate.t() | String.t() | nil,
+          filter: Predicate.t() | String.t(),
           as: [String.t()] | String.t() | nil,
-          calculate: String.t() | nil,
+          calculate: String.t(),
           default: String.t() | nil,
-          from: LookupData.t() | nil,
-          lookup: String.t() | nil,
-          bin: boolean() | BinParams.t() | nil,
-          field: String.t() | nil,
-          time_unit: TimeUnit.t() | nil,
-          aggregate: [AggregatedFieldDef.t()] | nil,
+          from: LookupData.t(),
+          lookup: String.t(),
+          bin: boolean() | BinParams.t(),
+          field: String.t(),
+          time_unit: TimeUnit.t(),
+          aggregate: [AggregatedFieldDef.t()],
           groupby: [String.t()] | nil
         }
 
-  def decode_filter(%{} = value), do: Predicate.from_map(value)
+  def decode_filter(%{"not" => _,"and" => _,"or" => _,"equal" => _,"field" => _,"range" => _,"oneOf" => _,"selection" => _,} = value), do: Predicate.from_map(value)
   def decode_filter(value) when is_binary(value), do: value
-  def decode_filter(value) when is_nil(value), do: value
   def decode_filter(_), do: {:error, "Unexpected type when decoding Transform.filter"}
 
   def encode_filter(%Predicate{} = value), do: Predicate.to_map(value)
   def encode_filter(value) when is_binary(value), do: value
-  def encode_filter(value) when is_nil(value), do: value
   def encode_filter(_), do: {:error, "Unexpected type when encoding Transform.filter"}
 
   def decode_as(value) when is_binary(value), do: value
@@ -7928,12 +7913,10 @@ defmodule Transform do
 
   def decode_bin(%{} = value), do: BinParams.from_map(value)
   def decode_bin(value) when is_boolean(value), do: value
-  def decode_bin(value) when is_nil(value), do: value
   def decode_bin(_), do: {:error, "Unexpected type when decoding Transform.bin"}
 
   def encode_bin(%BinParams{} = value), do: BinParams.to_map(value)
   def encode_bin(value) when is_boolean(value), do: value
-  def encode_bin(value) when is_nil(value), do: value
   def encode_bin(_), do: {:error, "Unexpected type when encoding Transform.bin"}
 
   def from_map(m) do
@@ -7942,12 +7925,12 @@ defmodule Transform do
       as: decode_as(m["as"]),
       calculate: m["calculate"],
       default: m["default"],
-      from: m["from"] && LookupData.from_map(m["from"]),
+      from: LookupData.from_map(m["from"]),
       lookup: m["lookup"],
       bin: decode_bin(m["bin"]),
       field: m["field"],
-      time_unit: m["timeUnit"] && TimeUnit.decode(m["timeUnit"]),
-      aggregate: m["aggregate"] && Enum.map(m["aggregate"], &AggregatedFieldDef.from_map/1),
+      time_unit: TimeUnit.decode(m["timeUnit"]),
+      aggregate: Enum.map(m["aggregate"], &AggregatedFieldDef.from_map/1),
       groupby: m["groupby"],
     }
   end
@@ -7964,11 +7947,11 @@ defmodule Transform do
       "as" => encode_as(struct.as),
       "calculate" => struct.calculate,
       "default" => struct.default,
-      "from" => struct.from && LookupData.to_map(struct.from),
+      "from" => LookupData.to_map(struct.from),
       "lookup" => struct.lookup,
       "bin" => encode_bin(struct.bin),
       "field" => struct.field,
-      "timeUnit" => struct.time_unit && TimeUnit.encode(struct.time_unit),
+      "timeUnit" => TimeUnit.encode(struct.time_unit),
       "aggregate" => struct.aggregate && Enum.map(struct.aggregate, &AggregatedFieldDef.to_map/1),
       "groupby" => struct.groupby,
     }
@@ -7999,20 +7982,21 @@ defmodule LayerSpec do
   - `:selection` - A key-value mapping between selection names and definitions.
   """
 
+  @enforce_keys [:layer, :encoding, :mark]
   defstruct [:data, :description, :height, :layer, :name, :resolve, :title, :transform, :width, :encoding, :mark, :projection, :selection]
 
   @type t :: %__MODULE__{
           data: Data.t() | nil,
           description: String.t() | nil,
           height: float() | nil,
-          layer: [LayerSpec.t()] | nil,
+          layer: [LayerSpec.t()],
           name: String.t() | nil,
           resolve: Resolve.t() | nil,
           title: TitleParams.t() | String.t() | nil,
           transform: [Transform.t()] | nil,
           width: float() | nil,
-          encoding: Encoding.t() | nil,
-          mark: MarkDef.t() | Mark.t() | nil,
+          encoding: Encoding.t(),
+          mark: MarkDef.t() | Mark.t(),
           projection: Projection.t() | nil,
           selection: %{String.t() => SelectionDef.t()} | nil
         }
@@ -8029,12 +8013,10 @@ defmodule LayerSpec do
 
   def decode_mark(%{"type" => _,} = value), do: MarkDef.from_map(value)
   def decode_mark(value) when is_binary(value), do: Mark.decode(value)
-  def decode_mark(value) when is_nil(value), do: value
   def decode_mark(_), do: {:error, "Unexpected type when decoding LayerSpec.mark"}
 
   def encode_mark(%MarkDef{} = value), do: MarkDef.to_map(value)
   def encode_mark(value) when is_atom(value), do: Mark.encode(value)
-  def encode_mark(value) when is_nil(value), do: value
   def encode_mark(_), do: {:error, "Unexpected type when encoding LayerSpec.mark"}
 
   def from_map(m) do
@@ -8042,13 +8024,13 @@ defmodule LayerSpec do
       data: m["data"] && Data.from_map(m["data"]),
       description: m["description"],
       height: m["height"],
-      layer: m["layer"] && Enum.map(m["layer"], &LayerSpec.from_map/1),
+      layer: Enum.map(m["layer"], &LayerSpec.from_map/1),
       name: m["name"],
       resolve: m["resolve"] && Resolve.from_map(m["resolve"]),
       title: decode_title(m["title"]),
       transform: m["transform"] && Enum.map(m["transform"], &Transform.from_map/1),
       width: m["width"],
-      encoding: m["encoding"] && Encoding.from_map(m["encoding"]),
+      encoding: Encoding.from_map(m["encoding"]),
       mark: decode_mark(m["mark"]),
       projection: m["projection"] && Projection.from_map(m["projection"]),
       selection: m["selection"]
@@ -8073,7 +8055,7 @@ defmodule LayerSpec do
       "title" => encode_title(struct.title),
       "transform" => struct.transform && Enum.map(struct.transform, &Transform.to_map/1),
       "width" => struct.width,
-      "encoding" => struct.encoding && Encoding.to_map(struct.encoding),
+      "encoding" => Encoding.to_map(struct.encoding),
       "mark" => encode_mark(struct.mark),
       "projection" => struct.projection && Projection.to_map(struct.projection),
       "selection" => struct.selection
@@ -8153,27 +8135,28 @@ defmodule Spec do
   - `:hconcat` - A list of views that should be concatenated and put into a row.
   """
 
+  @enforce_keys [:layer, :encoding, :mark, :facet, :spec, :repeat, :vconcat, :hconcat]
   defstruct [:data, :description, :height, :layer, :name, :resolve, :title, :transform, :width, :encoding, :mark, :projection, :selection, :facet, :spec, :repeat, :vconcat, :hconcat]
 
   @type t :: %__MODULE__{
           data: Data.t() | nil,
           description: String.t() | nil,
           height: float() | nil,
-          layer: [LayerSpec.t()] | nil,
+          layer: [LayerSpec.t()],
           name: String.t() | nil,
           resolve: Resolve.t() | nil,
           title: TitleParams.t() | String.t() | nil,
           transform: [Transform.t()] | nil,
           width: float() | nil,
-          encoding: Encoding.t() | nil,
-          mark: MarkDef.t() | Mark.t() | nil,
+          encoding: Encoding.t(),
+          mark: MarkDef.t() | Mark.t(),
           projection: Projection.t() | nil,
           selection: %{String.t() => SelectionDef.t()} | nil,
-          facet: FacetMapping.t() | nil,
-          spec: Spec.t() | nil,
-          repeat: Repeat.t() | nil,
-          vconcat: [Spec.t()] | nil,
-          hconcat: [Spec.t()] | nil
+          facet: FacetMapping.t(),
+          spec: Spec.t(),
+          repeat: Repeat.t(),
+          vconcat: [Spec.t()],
+          hconcat: [Spec.t()]
         }
 
   def decode_title(%{"text" => _,} = value), do: TitleParams.from_map(value)
@@ -8188,12 +8171,10 @@ defmodule Spec do
 
   def decode_mark(%{"type" => _,} = value), do: MarkDef.from_map(value)
   def decode_mark(value) when is_binary(value), do: Mark.decode(value)
-  def decode_mark(value) when is_nil(value), do: value
   def decode_mark(_), do: {:error, "Unexpected type when decoding Spec.mark"}
 
   def encode_mark(%MarkDef{} = value), do: MarkDef.to_map(value)
   def encode_mark(value) when is_atom(value), do: Mark.encode(value)
-  def encode_mark(value) when is_nil(value), do: value
   def encode_mark(_), do: {:error, "Unexpected type when encoding Spec.mark"}
 
   def from_map(m) do
@@ -8201,22 +8182,22 @@ defmodule Spec do
       data: m["data"] && Data.from_map(m["data"]),
       description: m["description"],
       height: m["height"],
-      layer: m["layer"] && Enum.map(m["layer"], &LayerSpec.from_map/1),
+      layer: Enum.map(m["layer"], &LayerSpec.from_map/1),
       name: m["name"],
       resolve: m["resolve"] && Resolve.from_map(m["resolve"]),
       title: decode_title(m["title"]),
       transform: m["transform"] && Enum.map(m["transform"], &Transform.from_map/1),
       width: m["width"],
-      encoding: m["encoding"] && Encoding.from_map(m["encoding"]),
+      encoding: Encoding.from_map(m["encoding"]),
       mark: decode_mark(m["mark"]),
       projection: m["projection"] && Projection.from_map(m["projection"]),
       selection: m["selection"]
       |> Map.new(fn {key, value} -> {key, SelectionDef.from_map(value)} end),
-      facet: m["facet"] && FacetMapping.from_map(m["facet"]),
-      spec: m["spec"] && Spec.from_map(m["spec"]),
-      repeat: m["repeat"] && Repeat.from_map(m["repeat"]),
-      vconcat: m["vconcat"] && Enum.map(m["vconcat"], &Spec.from_map/1),
-      hconcat: m["hconcat"] && Enum.map(m["hconcat"], &Spec.from_map/1),
+      facet: FacetMapping.from_map(m["facet"]),
+      spec: Spec.from_map(m["spec"]),
+      repeat: Repeat.from_map(m["repeat"]),
+      vconcat: Enum.map(m["vconcat"], &Spec.from_map/1),
+      hconcat: Enum.map(m["hconcat"], &Spec.from_map/1),
     }
   end
 
@@ -8237,14 +8218,14 @@ defmodule Spec do
       "title" => encode_title(struct.title),
       "transform" => struct.transform && Enum.map(struct.transform, &Transform.to_map/1),
       "width" => struct.width,
-      "encoding" => struct.encoding && Encoding.to_map(struct.encoding),
+      "encoding" => Encoding.to_map(struct.encoding),
       "mark" => encode_mark(struct.mark),
       "projection" => struct.projection && Projection.to_map(struct.projection),
       "selection" => struct.selection
       |> Map.new(fn {key, value} -> {key, SelectionDef.to_map(value)} end),
-      "facet" => struct.facet && FacetMapping.to_map(struct.facet),
-      "spec" => struct.spec && Spec.to_map(struct.spec),
-      "repeat" => struct.repeat && Repeat.to_map(struct.repeat),
+      "facet" => FacetMapping.to_map(struct.facet),
+      "spec" => Spec.to_map(struct.spec),
+      "repeat" => Repeat.to_map(struct.repeat),
       "vconcat" => struct.vconcat && Enum.map(struct.vconcat, &Spec.to_map/1),
       "hconcat" => struct.hconcat && Enum.map(struct.hconcat, &Spec.to_map/1),
     }
@@ -8284,6 +8265,7 @@ defmodule TopLevel do
   - `:hconcat` - A list of views that should be concatenated and put into a row.
   """
 
+  @enforce_keys [:encoding, :mark, :layer, :facet, :spec, :repeat, :vconcat, :hconcat]
   defstruct [:schema, :autosize, :background, :config, :data, :description, :encoding, :height, :mark, :name, :padding, :projection, :selection, :title, :transform, :width, :layer, :resolve, :facet, :spec, :repeat, :vconcat, :hconcat]
 
   @type t :: %__MODULE__{
@@ -8293,9 +8275,9 @@ defmodule TopLevel do
           config: ConfigClass.t() | nil,
           data: Data.t() | nil,
           description: String.t() | nil,
-          encoding: EncodingWithFacet.t() | nil,
+          encoding: EncodingWithFacet.t(),
           height: float() | nil,
-          mark: MarkDef.t() | Mark.t() | nil,
+          mark: MarkDef.t() | Mark.t(),
           name: String.t() | nil,
           padding: PaddingClass.t() | float() | nil,
           projection: Projection.t() | nil,
@@ -8303,13 +8285,13 @@ defmodule TopLevel do
           title: TitleParams.t() | String.t() | nil,
           transform: [Transform.t()] | nil,
           width: float() | nil,
-          layer: [LayerSpec.t()] | nil,
+          layer: [LayerSpec.t()],
           resolve: Resolve.t() | nil,
-          facet: FacetMapping.t() | nil,
-          spec: Spec.t() | nil,
-          repeat: Repeat.t() | nil,
-          vconcat: [Spec.t()] | nil,
-          hconcat: [Spec.t()] | nil
+          facet: FacetMapping.t(),
+          spec: Spec.t(),
+          repeat: Repeat.t(),
+          vconcat: [Spec.t()],
+          hconcat: [Spec.t()]
         }
 
   def decode_autosize(%{} = value), do: AutoSizeParams.from_map(value)
@@ -8324,12 +8306,10 @@ defmodule TopLevel do
 
   def decode_mark(%{"type" => _,} = value), do: MarkDef.from_map(value)
   def decode_mark(value) when is_binary(value), do: Mark.decode(value)
-  def decode_mark(value) when is_nil(value), do: value
   def decode_mark(_), do: {:error, "Unexpected type when decoding TopLevel.mark"}
 
   def encode_mark(%MarkDef{} = value), do: MarkDef.to_map(value)
   def encode_mark(value) when is_atom(value), do: Mark.encode(value)
-  def encode_mark(value) when is_nil(value), do: value
   def encode_mark(_), do: {:error, "Unexpected type when encoding TopLevel.mark"}
 
   def decode_padding(%{} = value), do: PaddingClass.from_map(value)
@@ -8362,7 +8342,7 @@ defmodule TopLevel do
       config: m["config"] && ConfigClass.from_map(m["config"]),
       data: m["data"] && Data.from_map(m["data"]),
       description: m["description"],
-      encoding: m["encoding"] && EncodingWithFacet.from_map(m["encoding"]),
+      encoding: EncodingWithFacet.from_map(m["encoding"]),
       height: m["height"],
       mark: decode_mark(m["mark"]),
       name: m["name"],
@@ -8373,13 +8353,13 @@ defmodule TopLevel do
       title: decode_title(m["title"]),
       transform: m["transform"] && Enum.map(m["transform"], &Transform.from_map/1),
       width: m["width"],
-      layer: m["layer"] && Enum.map(m["layer"], &LayerSpec.from_map/1),
+      layer: Enum.map(m["layer"], &LayerSpec.from_map/1),
       resolve: m["resolve"] && Resolve.from_map(m["resolve"]),
-      facet: m["facet"] && FacetMapping.from_map(m["facet"]),
-      spec: m["spec"] && Spec.from_map(m["spec"]),
-      repeat: m["repeat"] && Repeat.from_map(m["repeat"]),
-      vconcat: m["vconcat"] && Enum.map(m["vconcat"], &Spec.from_map/1),
-      hconcat: m["hconcat"] && Enum.map(m["hconcat"], &Spec.from_map/1),
+      facet: FacetMapping.from_map(m["facet"]),
+      spec: Spec.from_map(m["spec"]),
+      repeat: Repeat.from_map(m["repeat"]),
+      vconcat: Enum.map(m["vconcat"], &Spec.from_map/1),
+      hconcat: Enum.map(m["hconcat"], &Spec.from_map/1),
     }
   end
 
@@ -8397,7 +8377,7 @@ defmodule TopLevel do
       "config" => struct.config && ConfigClass.to_map(struct.config),
       "data" => struct.data && Data.to_map(struct.data),
       "description" => struct.description,
-      "encoding" => struct.encoding && EncodingWithFacet.to_map(struct.encoding),
+      "encoding" => EncodingWithFacet.to_map(struct.encoding),
       "height" => struct.height,
       "mark" => encode_mark(struct.mark),
       "name" => struct.name,
@@ -8410,9 +8390,9 @@ defmodule TopLevel do
       "width" => struct.width,
       "layer" => struct.layer && Enum.map(struct.layer, &LayerSpec.to_map/1),
       "resolve" => struct.resolve && Resolve.to_map(struct.resolve),
-      "facet" => struct.facet && FacetMapping.to_map(struct.facet),
-      "spec" => struct.spec && Spec.to_map(struct.spec),
-      "repeat" => struct.repeat && Repeat.to_map(struct.repeat),
+      "facet" => FacetMapping.to_map(struct.facet),
+      "spec" => Spec.to_map(struct.spec),
+      "repeat" => Repeat.to_map(struct.repeat),
       "vconcat" => struct.vconcat && Enum.map(struct.vconcat, &Spec.to_map/1),
       "hconcat" => struct.hconcat && Enum.map(struct.hconcat, &Spec.to_map/1),
     }
diff --git a/head/schema-elm/test/inputs/schema/required-in-any-of.schema/default/QuickType.elm b/head/schema-elm/test/inputs/schema/required-in-any-of.schema/default/QuickType.elm
new file mode 100644
index 0000000..4392015
--- /dev/null
+++ b/head/schema-elm/test/inputs/schema/required-in-any-of.schema/default/QuickType.elm
@@ -0,0 +1,70 @@
+-- To decode the JSON data, add this file to your project, run
+--
+--     elm install NoRedInk/elm-json-decode-pipeline
+--
+-- add these imports
+--
+--     import Json.Decode exposing (decodeString)
+--     import QuickType exposing (quickType)
+--
+-- and you're off to the races with
+--
+--     decodeString quickType myJsonString
+
+module QuickType exposing
+    ( QuickType
+    , quickTypeToString
+    , quickType
+    , Anyof
+    )
+
+import Json.Decode as Jdec
+import Json.Decode.Pipeline as Jpipe
+import Json.Encode as Jenc
+import Dict exposing (Dict)
+
+type alias QuickType =
+    { anyof : Anyof
+    }
+
+type alias Anyof =
+    { name : String
+    , size : Maybe String
+    }
+
+-- decoders and encoders
+
+quickTypeToString : QuickType -> String
+quickTypeToString r = Jenc.encode 0 (encodeQuickType r)
+
+quickType : Jdec.Decoder QuickType
+quickType =
+    Jdec.succeed QuickType
+        |> Jpipe.required "anyof" anyof
+
+encodeQuickType : QuickType -> Jenc.Value
+encodeQuickType x =
+    Jenc.object
+        [ ("anyof", encodeAnyof x.anyof)
+        ]
+
+anyof : Jdec.Decoder Anyof
+anyof =
+    Jdec.succeed Anyof
+        |> Jpipe.required "name" Jdec.string
+        |> Jpipe.optional "size" (Jdec.nullable Jdec.string) Nothing
+
+encodeAnyof : Anyof -> Jenc.Value
+encodeAnyof x =
+    Jenc.object
+        [ ("name", Jenc.string x.name)
+        , ("size", makeNullableEncoder Jenc.string x.size)
+        ]
+
+--- encoder helpers
+
+makeNullableEncoder : (a -> Jenc.Value) -> Maybe a -> Jenc.Value
+makeNullableEncoder f m =
+    case m of
+    Just x -> f x
+    Nothing -> Jenc.null
diff --git a/head/schema-flow/test/inputs/schema/required-in-any-of.schema/default/TopLevel.js b/head/schema-flow/test/inputs/schema/required-in-any-of.schema/default/TopLevel.js
new file mode 100644
index 0000000..39cf4af
--- /dev/null
+++ b/head/schema-flow/test/inputs/schema/required-in-any-of.schema/default/TopLevel.js
@@ -0,0 +1,197 @@
+// @flow
+
+// To parse this data:
+//
+//   const Convert = require("./TopLevel");
+//
+//   const topLevel = Convert.toTopLevel(json);
+//
+// These functions will throw an error if the JSON doesn't
+// match the expected interface, even if the JSON is valid.
+
+export type TopLevel = {
+    anyof: Anyof;
+};
+
+export type Anyof = {
+    name:  string;
+    size?: string;
+};
+
+// Converts JSON strings to/from your types
+// and asserts the results of JSON.parse at runtime
+function toTopLevel(json: string): TopLevel {
+    return cast(JSON.parse(json), r("TopLevel"));
+}
+
+function topLevelToJson(value: TopLevel): string {
+    return JSON.stringify(uncast(value, r("TopLevel")), null, 2);
+}
+
+function invalidValue(typ: any, val: any, key: any, parent: any = '') {
+    const prettyTyp = prettyTypeName(typ);
+    const parentText = parent ? ` on ${parent}` : '';
+    const keyText = key ? ` for key "${key}"` : '';
+    throw Error(`Invalid value${keyText}${parentText}. Expected ${prettyTyp} but got ${JSON.stringify(val)}`);
+}
+
+function prettyTypeName(typ: any): string {
+    if (Array.isArray(typ)) {
+        if (typ.length === 2 && typ[0] === undefined) {
+            return `an optional ${prettyTypeName(typ[1])}`;
+        } else {
+            return `one of [${typ.map(a => { return prettyTypeName(a); }).join(", ")}]`;
+        }
+    } else if (typeof typ === "object" && typ.literal !== undefined) {
+        return typ.literal;
+    } else {
+        return typeof typ;
+    }
+}
+
+function jsonToJSProps(typ: any): any {
+    if (typ.jsonToJS === undefined) {
+        const map: any = {};
+        typ.props.forEach((p: any) => map[p.json] = { key: p.js, typ: p.typ });
+        typ.jsonToJS = map;
+    }
+    return typ.jsonToJS;
+}
+
+function jsToJSONProps(typ: any): any {
+    if (typ.jsToJSON === undefined) {
+        const map: any = {};
+        typ.props.forEach((p: any) => map[p.js] = { key: p.json, typ: p.typ });
+        typ.jsToJSON = map;
+    }
+    return typ.jsToJSON;
+}
+
+function transform(val: any, typ: any, getProps: any, key: any = '', parent: any = ''): any {
+    function transformPrimitive(typ: string, val: any): any {
+        if (typeof typ === typeof val) return val;
+        return invalidValue(typ, val, key, parent);
+    }
+
+    function transformUnion(typs: any[], val: any): any {
+        // val must validate against one typ in typs
+        const l = typs.length;
+        for (let i = 0; i < l; i++) {
+            const typ = typs[i];
+            try {
+                return transform(val, typ, getProps);
+            } catch (_) {}
+        }
+        return invalidValue(typs, val, key, parent);
+    }
+
+    function transformEnum(cases: string[], val: any): any {
+        if (cases.indexOf(val) !== -1) return val;
+        return invalidValue(cases.map(a => { return l(a); }), val, key, parent);
+    }
+
+    function transformArray(typ: any, val: any): any {
+        // val must be an array with no invalid elements
+        if (!Array.isArray(val)) return invalidValue(l("array"), val, key, parent);
+        return val.map(el => transform(el, typ, getProps));
+    }
+
+    function transformDate(val: any): any {
+        if (val === null) {
+            return null;
+        }
+        const d = new Date(val);
+        if (isNaN(d.valueOf())) {
+            return invalidValue(l("Date"), val, key, parent);
+        }
+        return d;
+    }
+
+    function transformObject(props: { [k: string]: any }, additional: any, val: any): any {
+        if (val === null || typeof val !== "object" || Array.isArray(val)) {
+            return invalidValue(l(ref || "object"), val, key, parent);
+        }
+        const result: any = {};
+        Object.getOwnPropertyNames(props).forEach(key => {
+            const prop = props[key];
+            const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined;
+            result[prop.key] = transform(v, prop.typ, getProps, key, ref);
+        });
+        Object.getOwnPropertyNames(val).forEach(key => {
+            if (!Object.prototype.hasOwnProperty.call(props, key)) {
+                result[key] = transform(val[key], additional, getProps, key, ref);
+            }
+        });
+        return result;
+    }
+
+    if (typ === "any") return val;
+    if (typ === null) {
+        if (val === null) return val;
+        return invalidValue(typ, val, key, parent);
+    }
+    if (typ === false) return invalidValue(typ, val, key, parent);
+    let ref: any = undefined;
+    while (typeof typ === "object" && typ.ref !== undefined) {
+        ref = typ.ref;
+        typ = typeMap[typ.ref];
+    }
+    if (Array.isArray(typ)) return transformEnum(typ, val);
+    if (typeof typ === "object") {
+        return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val)
+            : typ.hasOwnProperty("arrayItems")    ? transformArray(typ.arrayItems, val)
+            : typ.hasOwnProperty("props")         ? transformObject(getProps(typ), typ.additional, val)
+            : invalidValue(typ, val, key, parent);
+    }
+    // Numbers can be parsed by Date but shouldn't be.
+    if (typ === Date && typeof val !== "number") return transformDate(val);
+    return transformPrimitive(typ, val);
+}
+
+function cast<T>(val: any, typ: any): T {
+    return transform(val, typ, jsonToJSProps);
+}
+
+function uncast<T>(val: T, typ: any): any {
+    return transform(val, typ, jsToJSONProps);
+}
+
+function l(typ: any) {
+    return { literal: typ };
+}
+
+function a(typ: any) {
+    return { arrayItems: typ };
+}
+
+function u(...typs: any[]) {
+    return { unionMembers: typs };
+}
+
+function o(props: any[], additional: any) {
+    return { props, additional };
+}
+
+function m(additional: any) {
+    const props: any[] = [];
+    return { props, additional };
+}
+
+function r(name: string) {
+    return { ref: name };
+}
+
+const typeMap: any = {
+    "TopLevel": o([
+        { json: "anyof", js: "anyof", typ: r("Anyof") },
+    ], false),
+    "Anyof": o([
+        { json: "name", js: "name", typ: "" },
+        { json: "size", js: "size", typ: u(undefined, "") },
+    ], false),
+};
+
+module.exports = {
+    "topLevelToJson": topLevelToJson,
+    "toTopLevel": toTopLevel,
+};
diff --git a/base/schema-flow/test/inputs/schema/vega-lite.schema/default/TopLevel.js b/head/schema-flow/test/inputs/schema/vega-lite.schema/default/TopLevel.js
index 988f4c8..1a2deca 100644
--- a/base/schema-flow/test/inputs/schema/vega-lite.schema/default/TopLevel.js
+++ b/head/schema-flow/test/inputs/schema/vega-lite.schema/default/TopLevel.js
@@ -49,7 +49,7 @@ export type TopLevel = {
     /**
      * A key-value mapping between encoding channels and definition of fields.
      */
-    encoding?: EncodingWithFacet;
+    encoding: EncodingWithFacet;
     /**
      * The height of a visualization.
      *
@@ -76,7 +76,7 @@ export type TopLevel = {
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      */
-    mark?: AnyMark;
+    mark: AnyMark;
     /**
      * Name of the visualization for later reference.
      */
@@ -138,7 +138,7 @@ export type TopLevel = {
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      */
-    layer?: LayerSpec[];
+    layer: LayerSpec[];
     /**
      * Scale, axis, and legend resolutions for layers.
      *
@@ -155,24 +155,24 @@ export type TopLevel = {
      * An object that describes mappings between `row` and `column` channels and their field
      * definitions.
      */
-    facet?: FacetMapping;
+    facet: FacetMapping;
     /**
      * A specification of the view that gets faceted.
      */
-    spec?: Spec;
+    spec: Spec;
     /**
      * An object that describes what fields should be repeated into views that are laid out as a
      * `row` or `column`.
      */
-    repeat?: Repeat;
+    repeat: Repeat;
     /**
      * A list of views that should be concatenated and put into a column.
      */
-    vconcat?: Spec[];
+    vconcat: Spec[];
     /**
      * A list of views that should be concatenated and put into a row.
      */
-    hconcat?: Spec[];
+    hconcat: Spec[];
 };
 
 /**
@@ -1827,8 +1827,8 @@ export type RangeConfigValue = TitleFontWeight[] | RangeConfigValueVGScheme;
 export type RangeConfigValueVGScheme = {
     count?:  number;
     extent?: number[];
-    scheme?: string;
-    step?:   number;
+    scheme:  string;
+    step:    number;
 };
 
 /**
@@ -2295,7 +2295,7 @@ export type SingleSelectionConfig = {
 export type VGBinding = {
     element?: string;
     input:    string;
-    options?: string[];
+    options:  string[];
     max?:     number;
     min?:     number;
     step?:    number;
@@ -3052,18 +3052,18 @@ export type Data = {
      * An URL from which to load the data set. Use the `format.type` property
      * to ensure the loaded data is correctly parsed.
      */
-    url?: string;
+    url: string;
     /**
      * The full data set, included inline. This can be an array of objects or primitive values
      * or a string.
      * Arrays of primitive values are ingested as objects with a `data` property. Strings are
      * parsed according to the specified format type.
      */
-    values?: Values;
+    values: Values;
     /**
      * Provide a placeholder name and bind data at runtime.
      */
-    name?: string;
+    name: string;
 };
 
 /**
@@ -3362,7 +3362,7 @@ export type MarkPropDefWithCondition = {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    type?: Type;
+    type: Type;
     /**
      * A constant value in visual domain.
      */
@@ -3468,7 +3468,7 @@ export type BinParams = {
 export type ColorCondition = ConditionalValueDef[] | ConditionalPredicateMarkPropFieldDefClass;
 
 export type ConditionalValueDef = {
-    test?: LogicalOperandPredicate;
+    test: LogicalOperandPredicate;
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
@@ -3478,13 +3478,13 @@ export type ConditionalValueDef = {
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
-    selection?: SelectionOperand;
+    selection: SelectionOperand;
 };
 
 export type Selection = {
-    not?: SelectionOperand;
-    and?: SelectionOperand[];
-    or?:  SelectionOperand[];
+    not: SelectionOperand;
+    and: SelectionOperand[];
+    or:  SelectionOperand[];
 };
 
 /**
@@ -3496,19 +3496,19 @@ export type Selection = {
 export type SelectionOperand = Selection | string;
 
 export type Predicate = {
-    not?: LogicalOperandPredicate;
-    and?: LogicalOperandPredicate[];
-    or?:  LogicalOperandPredicate[];
+    not: LogicalOperandPredicate;
+    and: LogicalOperandPredicate[];
+    or:  LogicalOperandPredicate[];
     /**
      * The value that the field should be equal to.
      */
-    equal?: Equal;
+    equal: Equal;
     /**
      * Field to be filtered.
      *
      * Field to be filtered
      */
-    field?: string;
+    field: string;
     /**
      * Time unit for the field to be filtered.
      *
@@ -3519,16 +3519,16 @@ export type Predicate = {
      * An array of inclusive minimum and maximum values
      * for a field value of a data item to be included in the filtered data.
      */
-    range?: RangeElement[];
+    range: RangeElement[];
     /**
      * A set of values that the `field`'s value should be a member of,
      * for a data item included in the filtered data.
      */
-    oneOf?: Equal[];
+    oneOf: Equal[];
     /**
      * Filter using a selection name.
      */
-    selection?: SelectionOperand;
+    selection: SelectionOperand;
 };
 
 /**
@@ -3689,17 +3689,17 @@ export type TimeUnit =
 export type ConditionalValueDefValue = boolean | number | string;
 
 export type ConditionalPredicateMarkPropFieldDefClass = {
-    test?: LogicalOperandPredicate;
+    test: LogicalOperandPredicate;
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    value?: ConditionalValueDefValue;
+    value: ConditionalValueDefValue;
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
-    selection?: SelectionOperand;
+    selection: SelectionOperand;
     /**
      * Aggregation function for the field
      * (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`).
@@ -3765,7 +3765,7 @@ export type ConditionalPredicateMarkPropFieldDefClass = {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    type?: Type;
+    type: Type;
 };
 
 export type Field = RepeatRef | string;
@@ -4540,7 +4540,7 @@ export type DefWithCondition = {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    type?: Type;
+    type: Type;
     /**
      * A constant value in visual domain.
      */
@@ -4550,17 +4550,17 @@ export type DefWithCondition = {
 export type HrefCondition = ConditionalValueDef[] | ConditionalPredicateFieldDefClass;
 
 export type ConditionalPredicateFieldDefClass = {
-    test?: LogicalOperandPredicate;
+    test: LogicalOperandPredicate;
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    value?: ConditionalValueDefValue;
+    value: ConditionalValueDefValue;
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
-    selection?: SelectionOperand;
+    selection: SelectionOperand;
     /**
      * Aggregation function for the field
      * (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`).
@@ -4602,7 +4602,7 @@ export type ConditionalPredicateFieldDefClass = {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    type?: Type;
+    type: Type;
 };
 
 export type Order = OrderFieldDef[] | OrderFieldDef;
@@ -4731,7 +4731,7 @@ export type TextDefWithCondition = {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    type?: Type;
+    type: Type;
     /**
      * A constant value in visual domain.
      */
@@ -4741,17 +4741,17 @@ export type TextDefWithCondition = {
 export type TextCondition = ConditionalValueDef[] | ConditionalPredicateTextFieldDefClass;
 
 export type ConditionalPredicateTextFieldDefClass = {
-    test?: LogicalOperandPredicate;
+    test: LogicalOperandPredicate;
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    value?: ConditionalValueDefValue;
+    value: ConditionalValueDefValue;
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
-    selection?: SelectionOperand;
+    selection: SelectionOperand;
     /**
      * Aggregation function for the field
      * (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`).
@@ -4798,7 +4798,7 @@ export type ConditionalPredicateTextFieldDefClass = {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    type?: Type;
+    type: Type;
 };
 
 /**
@@ -4897,12 +4897,12 @@ export type XClass = {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    type?: Type;
+    type: Type;
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    value?: ConditionalValueDefValue;
+    value: ConditionalValueDefValue;
 };
 
 export type Axis = {
@@ -5125,12 +5125,12 @@ export type X2Class = {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    type?: Type;
+    type: Type;
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    value?: ConditionalValueDefValue;
+    value: ConditionalValueDefValue;
 };
 
 /**
@@ -5186,7 +5186,7 @@ export type Spec = {
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      */
-    layer?: LayerSpec[];
+    layer: LayerSpec[];
     /**
      * Name of the visualization for later reference.
      */
@@ -5237,14 +5237,14 @@ export type Spec = {
     /**
      * A key-value mapping between encoding channels and definition of fields.
      */
-    encoding?: Encoding;
+    encoding: Encoding;
     /**
      * A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
      * `"line"`,
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      */
-    mark?: AnyMark;
+    mark: AnyMark;
     /**
      * An object defining properties of geographic projection.
      *
@@ -5260,24 +5260,24 @@ export type Spec = {
      * An object that describes mappings between `row` and `column` channels and their field
      * definitions.
      */
-    facet?: FacetMapping;
+    facet: FacetMapping;
     /**
      * A specification of the view that gets faceted.
      */
-    spec?: Spec;
+    spec: Spec;
     /**
      * An object that describes what fields should be repeated into views that are laid out as a
      * `row` or `column`.
      */
-    repeat?: Repeat;
+    repeat: Repeat;
     /**
      * A list of views that should be concatenated and put into a column.
      */
-    vconcat?: Spec[];
+    vconcat: Spec[];
     /**
      * A list of views that should be concatenated and put into a row.
      */
-    hconcat?: Spec[];
+    hconcat: Spec[];
 };
 
 /**
@@ -5402,7 +5402,7 @@ export type LayerSpec = {
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      */
-    layer?: LayerSpec[];
+    layer: LayerSpec[];
     /**
      * Name of the visualization for later reference.
      */
@@ -5445,14 +5445,14 @@ export type LayerSpec = {
     /**
      * A key-value mapping between encoding channels and definition of fields.
      */
-    encoding?: Encoding;
+    encoding: Encoding;
     /**
      * A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
      * `"line"`,
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      */
-    mark?: AnyMark;
+    mark: AnyMark;
     /**
      * An object defining properties of geographic projection.
      *
@@ -5995,7 +5995,7 @@ export type Transform = {
      * (3) a [selection predicate](filter.html#selection-predicate);
      * or (4) a logical operand that combines (1), (2), or (3).
      */
-    filter?: LogicalOperandPredicate;
+    filter: LogicalOperandPredicate;
     /**
      * The field for storing the computed formula value.
      *
@@ -6013,7 +6013,7 @@ export type Transform = {
      * A [expression](types.html#expression) string. Use the variable `datum` to refer to the
      * current data object.
      */
-    calculate?: string;
+    calculate: string;
     /**
      * The default value to use if lookup fails.
      *
@@ -6023,29 +6023,29 @@ export type Transform = {
     /**
      * Secondary data reference.
      */
-    from?: LookupData;
+    from: LookupData;
     /**
      * Key in primary data source.
      */
-    lookup?: string;
+    lookup: string;
     /**
      * An object indicating bin properties, or simply `true` for using default bin parameters.
      */
-    bin?: Bin;
+    bin: Bin;
     /**
      * The data field to bin.
      *
      * The data field to apply time unit.
      */
-    field?: string;
+    field: string;
     /**
      * The timeUnit.
      */
-    timeUnit?: TimeUnit;
+    timeUnit: TimeUnit;
     /**
      * Array of objects that define fields to aggregate.
      */
-    aggregate?: AggregatedFieldDef[];
+    aggregate: AggregatedFieldDef[];
     /**
      * The data fields to group by. If not specified, a single group containing all data objects
      * will be used.
@@ -6276,9 +6276,9 @@ const typeMap: any = {
         { json: "config", js: "config", typ: u(undefined, r("Config")) },
         { json: "data", js: "data", typ: u(undefined, r("Data")) },
         { json: "description", js: "description", typ: u(undefined, "") },
-        { json: "encoding", js: "encoding", typ: u(undefined, r("EncodingWithFacet")) },
+        { json: "encoding", js: "encoding", typ: r("EncodingWithFacet") },
         { json: "height", js: "height", typ: u(undefined, 3.14) },
-        { json: "mark", js: "mark", typ: u(undefined, u(r("MarkDef"), r("Mark"))) },
+        { json: "mark", js: "mark", typ: u(r("MarkDef"), r("Mark")) },
         { json: "name", js: "name", typ: u(undefined, "") },
         { json: "padding", js: "padding", typ: u(undefined, u(r("PaddingClass"), 3.14)) },
         { json: "projection", js: "projection", typ: u(undefined, r("Projection")) },
@@ -6286,13 +6286,13 @@ const typeMap: any = {
         { json: "title", js: "title", typ: u(undefined, u(r("TitleParams"), "")) },
         { json: "transform", js: "transform", typ: u(undefined, a(r("Transform"))) },
         { json: "width", js: "width", typ: u(undefined, 3.14) },
-        { json: "layer", js: "layer", typ: u(undefined, a(r("LayerSpec"))) },
+        { json: "layer", js: "layer", typ: a(r("LayerSpec")) },
         { json: "resolve", js: "resolve", typ: u(undefined, r("Resolve")) },
-        { json: "facet", js: "facet", typ: u(undefined, r("FacetMapping")) },
-        { json: "spec", js: "spec", typ: u(undefined, r("Spec")) },
-        { json: "repeat", js: "repeat", typ: u(undefined, r("Repeat")) },
-        { json: "vconcat", js: "vconcat", typ: u(undefined, a(r("Spec"))) },
-        { json: "hconcat", js: "hconcat", typ: u(undefined, a(r("Spec"))) },
+        { json: "facet", js: "facet", typ: r("FacetMapping") },
+        { json: "spec", js: "spec", typ: r("Spec") },
+        { json: "repeat", js: "repeat", typ: r("Repeat") },
+        { json: "vconcat", js: "vconcat", typ: a(r("Spec")) },
+        { json: "hconcat", js: "hconcat", typ: a(r("Spec")) },
     ], false),
     "AutoSizeParams": o([
         { json: "contains", js: "contains", typ: u(undefined, r("Contains")) },
@@ -6566,8 +6566,8 @@ const typeMap: any = {
     "RangeConfigValueVGScheme": o([
         { json: "count", js: "count", typ: u(undefined, 3.14) },
         { json: "extent", js: "extent", typ: u(undefined, a(3.14)) },
-        { json: "scheme", js: "scheme", typ: u(undefined, "") },
-        { json: "step", js: "step", typ: u(undefined, 3.14) },
+        { json: "scheme", js: "scheme", typ: "" },
+        { json: "step", js: "step", typ: 3.14 },
     ], false),
     "ScaleConfig": o([
         { json: "bandPaddingInner", js: "bandPaddingInner", typ: u(undefined, 3.14) },
@@ -6636,7 +6636,7 @@ const typeMap: any = {
     "VGBinding": o([
         { json: "element", js: "element", typ: u(undefined, "") },
         { json: "input", js: "input", typ: "" },
-        { json: "options", js: "options", typ: u(undefined, a("")) },
+        { json: "options", js: "options", typ: a("") },
         { json: "max", js: "max", typ: u(undefined, 3.14) },
         { json: "min", js: "min", typ: u(undefined, 3.14) },
         { json: "step", js: "step", typ: u(undefined, 3.14) },
@@ -6764,9 +6764,9 @@ const typeMap: any = {
     ], false),
     "Data": o([
         { json: "format", js: "format", typ: u(undefined, r("DataFormat")) },
-        { json: "url", js: "url", typ: u(undefined, "") },
-        { json: "values", js: "values", typ: u(undefined, u(a(u(true, 3.14, m("any"), "")), m("any"), "")) },
-        { json: "name", js: "name", typ: u(undefined, "") },
+        { json: "url", js: "url", typ: "" },
+        { json: "values", js: "values", typ: u(a(u(true, 3.14, m("any"), "")), m("any"), "") },
+        { json: "name", js: "name", typ: "" },
     ], false),
     "DataFormat": o([
         { json: "parse", js: "parse", typ: u(undefined, u(r("ParseEnum"), m("any"))) },
@@ -6801,7 +6801,7 @@ const typeMap: any = {
         { json: "scale", js: "scale", typ: u(undefined, r("Scale")) },
         { json: "sort", js: "sort", typ: u(undefined, u(r("SortField"), r("SortEnum"), null)) },
         { json: "timeUnit", js: "timeUnit", typ: u(undefined, r("TimeUnit")) },
-        { json: "type", js: "type", typ: u(undefined, r("Type")) },
+        { json: "type", js: "type", typ: r("Type") },
         { json: "value", js: "value", typ: u(undefined, u(true, 3.14, "")) },
     ], false),
     "BinParams": o([
@@ -6815,25 +6815,25 @@ const typeMap: any = {
         { json: "steps", js: "steps", typ: u(undefined, a(3.14)) },
     ], false),
     "ConditionalValueDef": o([
-        { json: "test", js: "test", typ: u(undefined, u(r("Predicate"), "")) },
+        { json: "test", js: "test", typ: u(r("Predicate"), "") },
         { json: "value", js: "value", typ: u(true, 3.14, "") },
-        { json: "selection", js: "selection", typ: u(undefined, u(r("Selection"), "")) },
+        { json: "selection", js: "selection", typ: u(r("Selection"), "") },
     ], false),
     "Selection": o([
-        { json: "not", js: "not", typ: u(undefined, u(r("Selection"), "")) },
-        { json: "and", js: "and", typ: u(undefined, a(u(r("Selection"), ""))) },
-        { json: "or", js: "or", typ: u(undefined, a(u(r("Selection"), ""))) },
+        { json: "not", js: "not", typ: u(r("Selection"), "") },
+        { json: "and", js: "and", typ: a(u(r("Selection"), "")) },
+        { json: "or", js: "or", typ: a(u(r("Selection"), "")) },
     ], false),
     "Predicate": o([
-        { json: "not", js: "not", typ: u(undefined, u(r("Predicate"), "")) },
-        { json: "and", js: "and", typ: u(undefined, a(u(r("Predicate"), ""))) },
-        { json: "or", js: "or", typ: u(undefined, a(u(r("Predicate"), ""))) },
-        { json: "equal", js: "equal", typ: u(undefined, u(true, r("DateTime"), 3.14, "")) },
-        { json: "field", js: "field", typ: u(undefined, "") },
+        { json: "not", js: "not", typ: u(r("Predicate"), "") },
+        { json: "and", js: "and", typ: a(u(r("Predicate"), "")) },
+        { json: "or", js: "or", typ: a(u(r("Predicate"), "")) },
+        { json: "equal", js: "equal", typ: u(true, r("DateTime"), 3.14, "") },
+        { json: "field", js: "field", typ: "" },
         { json: "timeUnit", js: "timeUnit", typ: u(undefined, r("TimeUnit")) },
-        { json: "range", js: "range", typ: u(undefined, a(u(r("DateTime"), 3.14, null))) },
-        { json: "oneOf", js: "oneOf", typ: u(undefined, a(u(true, r("DateTime"), 3.14, ""))) },
-        { json: "selection", js: "selection", typ: u(undefined, u(r("Selection"), "")) },
+        { json: "range", js: "range", typ: a(u(r("DateTime"), 3.14, null)) },
+        { json: "oneOf", js: "oneOf", typ: a(u(true, r("DateTime"), 3.14, "")) },
+        { json: "selection", js: "selection", typ: u(r("Selection"), "") },
     ], false),
     "DateTime": o([
         { json: "date", js: "date", typ: u(undefined, 3.14) },
@@ -6848,9 +6848,9 @@ const typeMap: any = {
         { json: "year", js: "year", typ: u(undefined, 3.14) },
     ], false),
     "ConditionalPredicateMarkPropFieldDefClass": o([
-        { json: "test", js: "test", typ: u(undefined, u(r("Predicate"), "")) },
-        { json: "value", js: "value", typ: u(undefined, u(true, 3.14, "")) },
-        { json: "selection", js: "selection", typ: u(undefined, u(r("Selection"), "")) },
+        { json: "test", js: "test", typ: u(r("Predicate"), "") },
+        { json: "value", js: "value", typ: u(true, 3.14, "") },
+        { json: "selection", js: "selection", typ: u(r("Selection"), "") },
         { json: "aggregate", js: "aggregate", typ: u(undefined, r("AggregateOp")) },
         { json: "bin", js: "bin", typ: u(undefined, u(true, r("BinParams"))) },
         { json: "field", js: "field", typ: u(undefined, u(r("RepeatRef"), "")) },
@@ -6858,7 +6858,7 @@ const typeMap: any = {
         { json: "scale", js: "scale", typ: u(undefined, r("Scale")) },
         { json: "sort", js: "sort", typ: u(undefined, u(r("SortField"), r("SortEnum"), null)) },
         { json: "timeUnit", js: "timeUnit", typ: u(undefined, r("TimeUnit")) },
-        { json: "type", js: "type", typ: u(undefined, r("Type")) },
+        { json: "type", js: "type", typ: r("Type") },
     ], false),
     "RepeatRef": o([
         { json: "repeat", js: "repeat", typ: r("RepeatEnum") },
@@ -6941,18 +6941,18 @@ const typeMap: any = {
         { json: "condition", js: "condition", typ: u(undefined, u(a(r("ConditionalValueDef")), r("ConditionalPredicateFieldDefClass"))) },
         { json: "field", js: "field", typ: u(undefined, u(r("RepeatRef"), "")) },
         { json: "timeUnit", js: "timeUnit", typ: u(undefined, r("TimeUnit")) },
-        { json: "type", js: "type", typ: u(undefined, r("Type")) },
+        { json: "type", js: "type", typ: r("Type") },
         { json: "value", js: "value", typ: u(undefined, u(true, 3.14, "")) },
     ], false),
     "ConditionalPredicateFieldDefClass": o([
-        { json: "test", js: "test", typ: u(undefined, u(r("Predicate"), "")) },
-        { json: "value", js: "value", typ: u(undefined, u(true, 3.14, "")) },
-        { json: "selection", js: "selection", typ: u(undefined, u(r("Selection"), "")) },
+        { json: "test", js: "test", typ: u(r("Predicate"), "") },
+        { json: "value", js: "value", typ: u(true, 3.14, "") },
+        { json: "selection", js: "selection", typ: u(r("Selection"), "") },
         { json: "aggregate", js: "aggregate", typ: u(undefined, r("AggregateOp")) },
         { json: "bin", js: "bin", typ: u(undefined, u(true, r("BinParams"))) },
         { json: "field", js: "field", typ: u(undefined, u(r("RepeatRef"), "")) },
         { json: "timeUnit", js: "timeUnit", typ: u(undefined, r("TimeUnit")) },
-        { json: "type", js: "type", typ: u(undefined, r("Type")) },
+        { json: "type", js: "type", typ: r("Type") },
     ], false),
     "OrderFieldDef": o([
         { json: "aggregate", js: "aggregate", typ: u(undefined, r("AggregateOp")) },
@@ -6969,19 +6969,19 @@ const typeMap: any = {
         { json: "field", js: "field", typ: u(undefined, u(r("RepeatRef"), "")) },
         { json: "format", js: "format", typ: u(undefined, "") },
         { json: "timeUnit", js: "timeUnit", typ: u(undefined, r("TimeUnit")) },
-        { json: "type", js: "type", typ: u(undefined, r("Type")) },
+        { json: "type", js: "type", typ: r("Type") },
         { json: "value", js: "value", typ: u(undefined, u(true, 3.14, "")) },
     ], false),
     "ConditionalPredicateTextFieldDefClass": o([
-        { json: "test", js: "test", typ: u(undefined, u(r("Predicate"), "")) },
-        { json: "value", js: "value", typ: u(undefined, u(true, 3.14, "")) },
-        { json: "selection", js: "selection", typ: u(undefined, u(r("Selection"), "")) },
+        { json: "test", js: "test", typ: u(r("Predicate"), "") },
+        { json: "value", js: "value", typ: u(true, 3.14, "") },
+        { json: "selection", js: "selection", typ: u(r("Selection"), "") },
         { json: "aggregate", js: "aggregate", typ: u(undefined, r("AggregateOp")) },
         { json: "bin", js: "bin", typ: u(undefined, u(true, r("BinParams"))) },
         { json: "field", js: "field", typ: u(undefined, u(r("RepeatRef"), "")) },
         { json: "format", js: "format", typ: u(undefined, "") },
         { json: "timeUnit", js: "timeUnit", typ: u(undefined, r("TimeUnit")) },
-        { json: "type", js: "type", typ: u(undefined, r("Type")) },
+        { json: "type", js: "type", typ: r("Type") },
     ], false),
     "XClass": o([
         { json: "aggregate", js: "aggregate", typ: u(undefined, r("AggregateOp")) },
@@ -6992,8 +6992,8 @@ const typeMap: any = {
         { json: "sort", js: "sort", typ: u(undefined, u(r("SortField"), r("SortEnum"), null)) },
         { json: "stack", js: "stack", typ: u(undefined, u(r("StackOffset"), null)) },
         { json: "timeUnit", js: "timeUnit", typ: u(undefined, r("TimeUnit")) },
-        { json: "type", js: "type", typ: u(undefined, r("Type")) },
-        { json: "value", js: "value", typ: u(undefined, u(true, 3.14, "")) },
+        { json: "type", js: "type", typ: r("Type") },
+        { json: "value", js: "value", typ: u(true, 3.14, "") },
     ], false),
     "Axis": o([
         { json: "domain", js: "domain", typ: u(undefined, true) },
@@ -7024,8 +7024,8 @@ const typeMap: any = {
         { json: "bin", js: "bin", typ: u(undefined, u(true, r("BinParams"))) },
         { json: "field", js: "field", typ: u(undefined, u(r("RepeatRef"), "")) },
         { json: "timeUnit", js: "timeUnit", typ: u(undefined, r("TimeUnit")) },
-        { json: "type", js: "type", typ: u(undefined, r("Type")) },
-        { json: "value", js: "value", typ: u(undefined, u(true, 3.14, "")) },
+        { json: "type", js: "type", typ: r("Type") },
+        { json: "value", js: "value", typ: u(true, 3.14, "") },
     ], false),
     "FacetMapping": o([
         { json: "column", js: "column", typ: u(undefined, r("FacetFieldDef")) },
@@ -7035,21 +7035,21 @@ const typeMap: any = {
         { json: "data", js: "data", typ: u(undefined, r("Data")) },
         { json: "description", js: "description", typ: u(undefined, "") },
         { json: "height", js: "height", typ: u(undefined, 3.14) },
-        { json: "layer", js: "layer", typ: u(undefined, a(r("LayerSpec"))) },
+        { json: "layer", js: "layer", typ: a(r("LayerSpec")) },
         { json: "name", js: "name", typ: u(undefined, "") },
         { json: "resolve", js: "resolve", typ: u(undefined, r("Resolve")) },
         { json: "title", js: "title", typ: u(undefined, u(r("TitleParams"), "")) },
         { json: "transform", js: "transform", typ: u(undefined, a(r("Transform"))) },
         { json: "width", js: "width", typ: u(undefined, 3.14) },
-        { json: "encoding", js: "encoding", typ: u(undefined, r("Encoding")) },
-        { json: "mark", js: "mark", typ: u(undefined, u(r("MarkDef"), r("Mark"))) },
+        { json: "encoding", js: "encoding", typ: r("Encoding") },
+        { json: "mark", js: "mark", typ: u(r("MarkDef"), r("Mark")) },
         { json: "projection", js: "projection", typ: u(undefined, r("Projection")) },
         { json: "selection", js: "selection", typ: u(undefined, m(r("SelectionDef"))) },
-        { json: "facet", js: "facet", typ: u(undefined, r("FacetMapping")) },
-        { json: "spec", js: "spec", typ: u(undefined, r("Spec")) },
-        { json: "repeat", js: "repeat", typ: u(undefined, r("Repeat")) },
-        { json: "vconcat", js: "vconcat", typ: u(undefined, a(r("Spec"))) },
-        { json: "hconcat", js: "hconcat", typ: u(undefined, a(r("Spec"))) },
+        { json: "facet", js: "facet", typ: r("FacetMapping") },
+        { json: "spec", js: "spec", typ: r("Spec") },
+        { json: "repeat", js: "repeat", typ: r("Repeat") },
+        { json: "vconcat", js: "vconcat", typ: a(r("Spec")) },
+        { json: "hconcat", js: "hconcat", typ: a(r("Spec")) },
     ], false),
     "Encoding": o([
         { json: "color", js: "color", typ: u(undefined, r("MarkPropDefWithCondition")) },
@@ -7070,14 +7070,14 @@ const typeMap: any = {
         { json: "data", js: "data", typ: u(undefined, r("Data")) },
         { json: "description", js: "description", typ: u(undefined, "") },
         { json: "height", js: "height", typ: u(undefined, 3.14) },
-        { json: "layer", js: "layer", typ: u(undefined, a(r("LayerSpec"))) },
+        { json: "layer", js: "layer", typ: a(r("LayerSpec")) },
         { json: "name", js: "name", typ: u(undefined, "") },
         { json: "resolve", js: "resolve", typ: u(undefined, r("Resolve")) },
         { json: "title", js: "title", typ: u(undefined, u(r("TitleParams"), "")) },
         { json: "transform", js: "transform", typ: u(undefined, a(r("Transform"))) },
         { json: "width", js: "width", typ: u(undefined, 3.14) },
-        { json: "encoding", js: "encoding", typ: u(undefined, r("Encoding")) },
-        { json: "mark", js: "mark", typ: u(undefined, u(r("MarkDef"), r("Mark"))) },
+        { json: "encoding", js: "encoding", typ: r("Encoding") },
+        { json: "mark", js: "mark", typ: u(r("MarkDef"), r("Mark")) },
         { json: "projection", js: "projection", typ: u(undefined, r("Projection")) },
         { json: "selection", js: "selection", typ: u(undefined, m(r("SelectionDef"))) },
     ], false),
@@ -7181,16 +7181,16 @@ const typeMap: any = {
         { json: "text", js: "text", typ: "" },
     ], false),
     "Transform": o([
-        { json: "filter", js: "filter", typ: u(undefined, u(r("Predicate"), "")) },
+        { json: "filter", js: "filter", typ: u(r("Predicate"), "") },
         { json: "as", js: "as", typ: u(undefined, u(a(""), "")) },
-        { json: "calculate", js: "calculate", typ: u(undefined, "") },
+        { json: "calculate", js: "calculate", typ: "" },
         { json: "default", js: "default", typ: u(undefined, "") },
-        { json: "from", js: "from", typ: u(undefined, r("LookupData")) },
-        { json: "lookup", js: "lookup", typ: u(undefined, "") },
-        { json: "bin", js: "bin", typ: u(undefined, u(true, r("BinParams"))) },
-        { json: "field", js: "field", typ: u(undefined, "") },
-        { json: "timeUnit", js: "timeUnit", typ: u(undefined, r("TimeUnit")) },
-        { json: "aggregate", js: "aggregate", typ: u(undefined, a(r("AggregatedFieldDef"))) },
+        { json: "from", js: "from", typ: r("LookupData") },
+        { json: "lookup", js: "lookup", typ: "" },
+        { json: "bin", js: "bin", typ: u(true, r("BinParams")) },
+        { json: "field", js: "field", typ: "" },
+        { json: "timeUnit", js: "timeUnit", typ: r("TimeUnit") },
+        { json: "aggregate", js: "aggregate", typ: a(r("AggregatedFieldDef")) },
         { json: "groupby", js: "groupby", typ: u(undefined, a("")) },
     ], false),
     "AggregatedFieldDef": o([
diff --git a/head/schema-golang/test/inputs/schema/required-in-any-of.schema/default/quicktype.go b/head/schema-golang/test/inputs/schema/required-in-any-of.schema/default/quicktype.go
new file mode 100644
index 0000000..424de4f
--- /dev/null
+++ b/head/schema-golang/test/inputs/schema/required-in-any-of.schema/default/quicktype.go
@@ -0,0 +1,28 @@
+// Code generated from JSON Schema using quicktype. DO NOT EDIT.
+// To parse and unparse this JSON data, add this code to your project and do:
+//
+//    topLevel, err := UnmarshalTopLevel(bytes)
+//    bytes, err = topLevel.Marshal()
+
+package main
+
+import "encoding/json"
+
+func UnmarshalTopLevel(data []byte) (TopLevel, error) {
+	var r TopLevel
+	err := json.Unmarshal(data, &r)
+	return r, err
+}
+
+func (r *TopLevel) Marshal() ([]byte, error) {
+	return json.Marshal(r)
+}
+
+type TopLevel struct {
+	Anyof Anyof `json:"anyof"`
+}
+
+type Anyof struct {
+	Name string  `json:"name"`
+	Size *string `json:"size,omitempty"`
+}
diff --git a/base/schema-golang/test/inputs/schema/vega-lite.schema/default/quicktype.go b/head/schema-golang/test/inputs/schema/vega-lite.schema/default/quicktype.go
index fc334b8..722ead3 100644
--- a/base/schema-golang/test/inputs/schema/vega-lite.schema/default/quicktype.go
+++ b/head/schema-golang/test/inputs/schema/vega-lite.schema/default/quicktype.go
@@ -47,7 +47,7 @@ type TopLevel struct {
 	// Description of this mark for commenting purpose.                                                                 
 	Description                                                                                 *string                 `json:"description,omitempty"`
 	// A key-value mapping between encoding channels and definition of fields.                                          
-	Encoding                                                                                    *EncodingWithFacet      `json:"encoding,omitempty"`
+	Encoding                                                                                    EncodingWithFacet       `json:"encoding"`
 	// The height of a visualization.                                                                                   
 	//                                                                                                                  
 	// __Default value:__                                                                                               
@@ -116,7 +116,7 @@ type TopLevel struct {
 	//                                                                                                                  
 	// __Note__: Specifications inside `layer` cannot use `row` and `column` channels as                                
 	// layering facet specifications is not allowed.                                                                    
-	Layer                                                                                       []LayerSpec             `json:"layer,omitempty"`
+	Layer                                                                                       []LayerSpec             `json:"layer"`
 	// Scale, axis, and legend resolutions for layers.                                                                  
 	//                                                                                                                  
 	// Scale, axis, and legend resolutions for facets.                                                                  
@@ -129,16 +129,16 @@ type TopLevel struct {
 	Resolve                                                                                     *Resolve                `json:"resolve,omitempty"`
 	// An object that describes mappings between `row` and `column` channels and their field                            
 	// definitions.                                                                                                     
-	Facet                                                                                       *FacetMapping           `json:"facet,omitempty"`
+	Facet                                                                                       FacetMapping            `json:"facet"`
 	// A specification of the view that gets faceted.                                                                   
-	Spec                                                                                        *Spec                   `json:"spec,omitempty"`
+	Spec                                                                                        Spec                    `json:"spec"`
 	// An object that describes what fields should be repeated into views that are laid out as a                        
 	// `row` or `column`.                                                                                               
-	Repeat                                                                                      *Repeat                 `json:"repeat,omitempty"`
+	Repeat                                                                                      Repeat                  `json:"repeat"`
 	// A list of views that should be concatenated and put into a column.                                               
-	Vconcat                                                                                     []Spec                  `json:"vconcat,omitempty"`
+	Vconcat                                                                                     []Spec                  `json:"vconcat"`
 	// A list of views that should be concatenated and put into a row.                                                  
-	Hconcat                                                                                     []Spec                  `json:"hconcat,omitempty"`
+	Hconcat                                                                                     []Spec                  `json:"hconcat"`
 }
 
 type AutoSizeParams struct {
@@ -992,7 +992,7 @@ type ProjectionConfig struct {
 type VGScheme struct {
 	Count  *float64  `json:"count,omitempty"`
 	Extent []float64 `json:"extent,omitempty"`
-	Scheme *string   `json:"scheme,omitempty"`
+	Scheme string    `json:"scheme"`
 	Step   *float64  `json:"step,omitempty"`
 }
 
@@ -1274,7 +1274,7 @@ type SingleSelectionConfig struct {
 type VGBinding struct {
 	Element *string  `json:"element,omitempty"`
 	Input   string   `json:"input"`
-	Options []string `json:"options,omitempty"`
+	Options []string `json:"options"`
 	Max     *float64 `json:"max,omitempty"`
 	Min     *float64 `json:"min,omitempty"`
 	Step    *float64 `json:"step,omitempty"`
@@ -1752,14 +1752,14 @@ type Data struct {
 	Format                                                                                    *DataFormat  `json:"format,omitempty"`
 	// An URL from which to load the data set. Use the `format.type` property                              
 	// to ensure the loaded data is correctly parsed.                                                      
-	URL                                                                                       *string      `json:"url,omitempty"`
+	URL                                                                                       string       `json:"url"`
 	// The full data set, included inline. This can be an array of objects or primitive values             
 	// or a string.                                                                                        
 	// Arrays of primitive values are ingested as objects with a `data` property. Strings are              
 	// parsed according to the specified format type.                                                      
 	Values                                                                                    *ValuesUnion `json:"values"`
 	// Provide a placeholder name and bind data at runtime.                                                
-	Name                                                                                      *string      `json:"name,omitempty"`
+	Name                                                                                      string       `json:"name"`
 }
 
 // An object that specifies the format for parsing the data file.
@@ -1968,7 +1968,7 @@ type MarkPropDefWithCondition struct {
 	// `"nominal"`).                                                                                                     
 	// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a                                   
 	// [geographic projection](projection.html) is applied.                                                              
-	Type                                                                                       *Type                     `json:"type,omitempty"`
+	Type                                                                                       Type                      `json:"type"`
 	// A constant value in visual domain.                                                                                
 	Value                                                                                      *ConditionalValueDefValue `json:"value"`
 }
@@ -2018,30 +2018,30 @@ type ConditionalValueDef struct {
 
 type Selection struct {
 	Not *SelectionOperand  `json:"not"`
-	And []SelectionOperand `json:"and,omitempty"`
-	Or  []SelectionOperand `json:"or,omitempty"`
+	And []SelectionOperand `json:"and"`
+	Or  []SelectionOperand `json:"or"`
 }
 
 type Predicate struct {
 	Not                                                                     *LogicalOperandPredicate  `json:"not"`
-	And                                                                     []LogicalOperandPredicate `json:"and,omitempty"`
-	Or                                                                      []LogicalOperandPredicate `json:"or,omitempty"`
+	And                                                                     []LogicalOperandPredicate `json:"and"`
+	Or                                                                      []LogicalOperandPredicate `json:"or"`
 	// The value that the field should be equal to.                                                   
 	Equal                                                                   *Equal                    `json:"equal"`
 	// Field to be filtered.                                                                          
 	//                                                                                                
 	// Field to be filtered                                                                           
-	Field                                                                   *string                   `json:"field,omitempty"`
+	Field                                                                   string                    `json:"field"`
 	// Time unit for the field to be filtered.                                                        
 	//                                                                                                
 	// time unit for the field to be filtered.                                                        
 	TimeUnit                                                                *TimeUnit                 `json:"timeUnit,omitempty"`
 	// An array of inclusive minimum and maximum values                                               
 	// for a field value of a data item to be included in the filtered data.                          
-	Range                                                                   []RangeElement            `json:"range,omitempty"`
+	Range                                                                   []RangeElement            `json:"range"`
 	// A set of values that the `field`'s value should be a member of,                                
 	// for a data item included in the filtered data.                                                 
-	OneOf                                                                   []Equal                   `json:"oneOf,omitempty"`
+	OneOf                                                                   []Equal                   `json:"oneOf"`
 	// Filter using a selection name.                                                                 
 	Selection                                                               *SelectionOperand         `json:"selection"`
 }
@@ -2137,7 +2137,7 @@ type ConditionalPredicateMarkPropFieldDefClass struct {
 	// `"nominal"`).                                                                                                     
 	// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a                                   
 	// [geographic projection](projection.html) is applied.                                                              
-	Type                                                                                       *Type                     `json:"type,omitempty"`
+	Type                                                                                       Type                      `json:"type"`
 }
 
 // Reference to a repeated value.
@@ -2597,7 +2597,7 @@ type DefWithCondition struct {
 	// `"nominal"`).                                                                                                     
 	// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a                                   
 	// [geographic projection](projection.html) is applied.                                                              
-	Type                                                                                       *Type                     `json:"type,omitempty"`
+	Type                                                                                       Type                      `json:"type"`
 	// A constant value in visual domain.                                                                                
 	Value                                                                                      *ConditionalValueDefValue `json:"value"`
 }
@@ -2641,7 +2641,7 @@ type ConditionalPredicateFieldDefClass struct {
 	// `"nominal"`).                                                                                                     
 	// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a                                   
 	// [geographic projection](projection.html) is applied.                                                              
-	Type                                                                                       *Type                     `json:"type,omitempty"`
+	Type                                                                                       Type                      `json:"type"`
 }
 
 type OrderFieldDef struct {
@@ -2740,7 +2740,7 @@ type TextDefWithCondition struct {
 	// `"nominal"`).                                                                                                     
 	// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a                                   
 	// [geographic projection](projection.html) is applied.                                                              
-	Type                                                                                       *Type                     `json:"type,omitempty"`
+	Type                                                                                       Type                      `json:"type"`
 	// A constant value in visual domain.                                                                                
 	Value                                                                                      *ConditionalValueDefValue `json:"value"`
 }
@@ -2787,7 +2787,7 @@ type ConditionalPredicateTextFieldDefClass struct {
 	// `"nominal"`).                                                                                                     
 	// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a                                   
 	// [geographic projection](projection.html) is applied.                                                              
-	Type                                                                                       *Type                     `json:"type,omitempty"`
+	Type                                                                                       Type                      `json:"type"`
 }
 
 // X coordinates of the marks, or width of horizontal `"bar"` and `"area"`.
@@ -2866,7 +2866,7 @@ type XClass struct {
 	// `"nominal"`).                                                                                                      
 	// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a                                    
 	// [geographic projection](projection.html) is applied.                                                               
-	Type                                                                                        *Type                     `json:"type,omitempty"`
+	Type                                                                                        Type                      `json:"type"`
 	// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between                             
 	// `0` to `1` for opacity).                                                                                           
 	Value                                                                                       *ConditionalValueDefValue `json:"value"`
@@ -3034,7 +3034,7 @@ type X2Class struct {
 	// `"nominal"`).                                                                                                     
 	// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a                                   
 	// [geographic projection](projection.html) is applied.                                                              
-	Type                                                                                       *Type                     `json:"type,omitempty"`
+	Type                                                                                       Type                      `json:"type"`
 	// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between                            
 	// `0` to `1` for opacity).                                                                                          
 	Value                                                                                      *ConditionalValueDefValue `json:"value"`
@@ -3077,7 +3077,7 @@ type Spec struct {
 	//                                                                                                                  
 	// __Note__: Specifications inside `layer` cannot use `row` and `column` channels as                                
 	// layering facet specifications is not allowed.                                                                    
-	Layer                                                                                       []LayerSpec             `json:"layer,omitempty"`
+	Layer                                                                                       []LayerSpec             `json:"layer"`
 	// Name of the visualization for later reference.                                                                   
 	Name                                                                                        *string                 `json:"name,omitempty"`
 	// Scale, axis, and legend resolutions for layers.                                                                  
@@ -3116,7 +3116,7 @@ type Spec struct {
 	// __See also:__ The documentation for [width and height](size.html) contains more examples.                        
 	Width                                                                                       *float64                `json:"width,omitempty"`
 	// A key-value mapping between encoding channels and definition of fields.                                          
-	Encoding                                                                                    *Encoding               `json:"encoding,omitempty"`
+	Encoding                                                                                    Encoding                `json:"encoding"`
 	// A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,                             
 	// `"line"`,                                                                                                        
 	// * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition                               
@@ -3131,16 +3131,16 @@ type Spec struct {
 	Selection                                                                                   map[string]SelectionDef `json:"selection,omitempty"`
 	// An object that describes mappings between `row` and `column` channels and their field                            
 	// definitions.                                                                                                     
-	Facet                                                                                       *FacetMapping           `json:"facet,omitempty"`
+	Facet                                                                                       FacetMapping            `json:"facet"`
 	// A specification of the view that gets faceted.                                                                   
-	Spec                                                                                        *Spec                   `json:"spec,omitempty"`
+	Spec                                                                                        Spec                    `json:"spec"`
 	// An object that describes what fields should be repeated into views that are laid out as a                        
 	// `row` or `column`.                                                                                               
-	Repeat                                                                                      *Repeat                 `json:"repeat,omitempty"`
+	Repeat                                                                                      Repeat                  `json:"repeat"`
 	// A list of views that should be concatenated and put into a column.                                               
-	Vconcat                                                                                     []Spec                  `json:"vconcat,omitempty"`
+	Vconcat                                                                                     []Spec                  `json:"vconcat"`
 	// A list of views that should be concatenated and put into a row.                                                  
-	Hconcat                                                                                     []Spec                  `json:"hconcat,omitempty"`
+	Hconcat                                                                                     []Spec                  `json:"hconcat"`
 }
 
 // A key-value mapping between encoding channels and definition of fields.
@@ -3227,7 +3227,7 @@ type LayerSpec struct {
 	//                                                                                                                  
 	// __Note__: Specifications inside `layer` cannot use `row` and `column` channels as                                
 	// layering facet specifications is not allowed.                                                                    
-	Layer                                                                                       []LayerSpec             `json:"layer,omitempty"`
+	Layer                                                                                       []LayerSpec             `json:"layer"`
 	// Name of the visualization for later reference.                                                                   
 	Name                                                                                        *string                 `json:"name,omitempty"`
 	// Scale, axis, and legend resolutions for layers.                                                                  
@@ -3258,7 +3258,7 @@ type LayerSpec struct {
 	// __See also:__ The documentation for [width and height](size.html) contains more examples.                        
 	Width                                                                                       *float64                `json:"width,omitempty"`
 	// A key-value mapping between encoding channels and definition of fields.                                          
-	Encoding                                                                                    *Encoding               `json:"encoding,omitempty"`
+	Encoding                                                                                    Encoding                `json:"encoding"`
 	// A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,                             
 	// `"line"`,                                                                                                        
 	// * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition                               
@@ -3624,25 +3624,25 @@ type Transform struct {
 	As                                                                                          *Style                   `json:"as"`
 	// A [expression](types.html#expression) string. Use the variable `datum` to refer to the                            
 	// current data object.                                                                                              
-	Calculate                                                                                   *string                  `json:"calculate,omitempty"`
+	Calculate                                                                                   string                   `json:"calculate"`
 	// The default value to use if lookup fails.                                                                         
 	//                                                                                                                   
 	// __Default value:__ `null`                                                                                         
 	Default                                                                                     *string                  `json:"default,omitempty"`
 	// Secondary data reference.                                                                                         
-	From                                                                                        *LookupData              `json:"from,omitempty"`
+	From                                                                                        LookupData               `json:"from"`
 	// Key in primary data source.                                                                                       
-	Lookup                                                                                      *string                  `json:"lookup,omitempty"`
+	Lookup                                                                                      string                   `json:"lookup"`
 	// An object indicating bin properties, or simply `true` for using default bin parameters.                           
 	Bin                                                                                         *Bin                     `json:"bin"`
 	// The data field to bin.                                                                                            
 	//                                                                                                                   
 	// The data field to apply time unit.                                                                                
-	Field                                                                                       *string                  `json:"field,omitempty"`
+	Field                                                                                       string                   `json:"field"`
 	// The timeUnit.                                                                                                     
-	TimeUnit                                                                                    *TimeUnit                `json:"timeUnit,omitempty"`
+	TimeUnit                                                                                    TimeUnit                 `json:"timeUnit"`
 	// Array of objects that define fields to aggregate.                                                                 
-	Aggregate                                                                                   []AggregatedFieldDef     `json:"aggregate,omitempty"`
+	Aggregate                                                                                   []AggregatedFieldDef     `json:"aggregate"`
 	// The data fields to group by. If not specified, a single group containing all data objects                         
 	// will be used.                                                                                                     
 	Groupby                                                                                     []string                 `json:"groupby,omitempty"`
diff --git a/head/schema-haskell/test/inputs/schema/required-in-any-of.schema/default/QuickType.hs b/head/schema-haskell/test/inputs/schema/required-in-any-of.schema/default/QuickType.hs
new file mode 100644
index 0000000..3559746
--- /dev/null
+++ b/head/schema-haskell/test/inputs/schema/required-in-any-of.schema/default/QuickType.hs
@@ -0,0 +1,48 @@
+{-# LANGUAGE StrictData #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+module QuickType
+    ( QuickType (..)
+    , Anyof (..)
+    , decodeTopLevel
+    ) where
+
+import Data.Aeson
+import Data.Aeson.Types (emptyObject)
+import Data.ByteString.Lazy (ByteString)
+import Data.HashMap.Strict (HashMap)
+import Data.Text (Text)
+
+data QuickType = QuickType
+    { anyofQuickType :: Anyof
+    } deriving (Show)
+
+data Anyof = Anyof
+    { nameAnyof :: Text
+    , sizeAnyof :: Maybe Text
+    } deriving (Show)
+
+decodeTopLevel :: ByteString -> Maybe QuickType
+decodeTopLevel = decode
+
+instance ToJSON QuickType where
+    toJSON (QuickType anyofQuickType) =
+        object
+        [ "anyof" .= anyofQuickType
+        ]
+
+instance FromJSON QuickType where
+    parseJSON (Object v) = QuickType
+        <$> v .: "anyof"
+
+instance ToJSON Anyof where
+    toJSON (Anyof nameAnyof sizeAnyof) =
+        object
+        [ "name" .= nameAnyof
+        , "size" .= sizeAnyof
+        ]
+
+instance FromJSON Anyof where
+    parseJSON (Object v) = Anyof
+        <$> v .: "name"
+        <*> v .:? "size"
diff --git a/base/schema-haskell/test/inputs/schema/vega-lite.schema/default/QuickType.hs b/head/schema-haskell/test/inputs/schema/vega-lite.schema/default/QuickType.hs
index 2a0a7c9..02dc4d6 100644
--- a/base/schema-haskell/test/inputs/schema/vega-lite.schema/default/QuickType.hs
+++ b/head/schema-haskell/test/inputs/schema/vega-lite.schema/default/QuickType.hs
@@ -299,9 +299,9 @@ data QuickType = QuickType
     , configQuickType :: Maybe Config
     , quickTypeDataQuickType :: Maybe Data
     , descriptionQuickType :: Maybe Text
-    , encodingQuickType :: Maybe EncodingWithFacet
+    , encodingQuickType :: EncodingWithFacet
     , heightQuickType :: Maybe Float
-    , markQuickType :: Maybe AnyMark
+    , markQuickType :: AnyMark
     , nameQuickType :: Maybe Text
     , paddingQuickType :: Maybe Padding
     , projectionQuickType :: Maybe Projection
@@ -309,13 +309,13 @@ data QuickType = QuickType
     , titleQuickType :: Maybe Title
     , transformQuickType :: Maybe ([Transform])
     , widthQuickType :: Maybe Float
-    , layerQuickType :: Maybe ([LayerSpec])
+    , layerQuickType :: [LayerSpec]
     , resolveQuickType :: Maybe Resolve
-    , facetQuickType :: Maybe FacetMapping
-    , specQuickType :: Maybe Spec
-    , repeatQuickType :: Maybe Repeat
-    , vconcatQuickType :: Maybe ([Spec])
-    , hconcatQuickType :: Maybe ([Spec])
+    , facetQuickType :: FacetMapping
+    , specQuickType :: Spec
+    , repeatQuickType :: Repeat
+    , vconcatQuickType :: [Spec]
+    , hconcatQuickType :: [Spec]
     } deriving (Show)
 
 {-| Sets how the visualization size should be determined. If a string, should be one of
@@ -2106,7 +2106,7 @@ data RangeConfigValue
 data VGScheme = VGScheme
     { countVGScheme :: Maybe Float
     , extentVGScheme :: Maybe ([Float])
-    , schemeVGScheme :: Maybe Text
+    , schemeVGScheme :: Text
     , stepVGScheme :: Maybe Float
     } deriving (Show)
 
@@ -2571,7 +2571,7 @@ data SingleSelectionConfig = SingleSelectionConfig
 data VGBinding = VGBinding
     { elementVGBinding :: Maybe Text
     , inputVGBinding :: Text
-    , optionsVGBinding :: Maybe ([Text])
+    , optionsVGBinding :: [Text]
     , maxVGBinding :: Maybe Float
     , minVGBinding :: Maybe Float
     , stepVGBinding :: Maybe Float
@@ -3325,7 +3325,7 @@ data MarkPropDefWithCondition = MarkPropDefWithCondition
     , scaleMarkPropDefWithCondition :: Maybe Scale
     , sortMarkPropDefWithCondition :: Maybe SortUnion
     , timeUnitMarkPropDefWithCondition :: Maybe TimeUnit
-    , markPropDefWithConditionTypeMarkPropDefWithCondition :: Maybe Type
+    , markPropDefWithConditionTypeMarkPropDefWithCondition :: Type
     , valueMarkPropDefWithCondition :: Maybe ConditionalValueDefValue
     } deriving (Show)
 
@@ -3441,15 +3441,15 @@ A [selection name](selection.html), or a series of [composed
 selections](selection.html#compose).
 -}
 data ConditionalValueDef = ConditionalValueDef
-    { testConditionalValueDef :: Maybe LogicalOperandPredicate
+    { testConditionalValueDef :: LogicalOperandPredicate
     , valueConditionalValueDef :: ConditionalValueDefValue
-    , selectionConditionalValueDef :: Maybe SelectionOperand
+    , selectionConditionalValueDef :: SelectionOperand
     } deriving (Show)
 
 data Selection = Selection
-    { notSelection :: Maybe SelectionOperand
-    , andSelection :: Maybe ([SelectionOperand])
-    , orSelection :: Maybe ([SelectionOperand])
+    { notSelection :: SelectionOperand
+    , andSelection :: [SelectionOperand]
+    , orSelection :: [SelectionOperand]
     } deriving (Show)
 
 {-| Filter using a selection name.
@@ -3487,15 +3487,15 @@ selection:
 Filter using a selection name.
 -}
 data Predicate = Predicate
-    { notPredicate :: Maybe LogicalOperandPredicate
-    , andPredicate :: Maybe ([LogicalOperandPredicate])
-    , orPredicate :: Maybe ([LogicalOperandPredicate])
-    , equalPredicate :: Maybe Equal
-    , fieldPredicate :: Maybe Text
+    { notPredicate :: LogicalOperandPredicate
+    , andPredicate :: [LogicalOperandPredicate]
+    , orPredicate :: [LogicalOperandPredicate]
+    , equalPredicate :: Equal
+    , fieldPredicate :: Text
     , timeUnitPredicate :: Maybe TimeUnit
-    , rangePredicate :: Maybe ([RangeElement])
-    , oneOfPredicate :: Maybe ([Equal])
-    , selectionPredicate :: Maybe SelectionOperand
+    , rangePredicate :: [RangeElement]
+    , oneOfPredicate :: [Equal]
+    , selectionPredicate :: SelectionOperand
     } deriving (Show)
 
 {-| The `filter` property must be one of the predicate definitions:
@@ -3738,9 +3738,9 @@ It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
 [geographic projection](projection.html) is applied.
 -}
 data ConditionalPredicateMarkPropFieldDefClass = ConditionalPredicateMarkPropFieldDefClass
-    { testConditionalPredicateMarkPropFieldDefClass :: Maybe LogicalOperandPredicate
-    , valueConditionalPredicateMarkPropFieldDefClass :: Maybe ConditionalValueDefValue
-    , selectionConditionalPredicateMarkPropFieldDefClass :: Maybe SelectionOperand
+    { testConditionalPredicateMarkPropFieldDefClass :: LogicalOperandPredicate
+    , valueConditionalPredicateMarkPropFieldDefClass :: ConditionalValueDefValue
+    , selectionConditionalPredicateMarkPropFieldDefClass :: SelectionOperand
     , aggregateConditionalPredicateMarkPropFieldDefClass :: Maybe AggregateOp
     , binConditionalPredicateMarkPropFieldDefClass :: Maybe Bin
     , fieldConditionalPredicateMarkPropFieldDefClass :: Maybe Field
@@ -3748,7 +3748,7 @@ data ConditionalPredicateMarkPropFieldDefClass = ConditionalPredicateMarkPropFie
     , scaleConditionalPredicateMarkPropFieldDefClass :: Maybe Scale
     , sortConditionalPredicateMarkPropFieldDefClass :: Maybe SortUnion
     , timeUnitConditionalPredicateMarkPropFieldDefClass :: Maybe TimeUnit
-    , conditionalDefTypeConditionalPredicateMarkPropFieldDefClass :: Maybe Type
+    , conditionalDefTypeConditionalPredicateMarkPropFieldDefClass :: Type
     } deriving (Show)
 
 {-| The encoded field's type of measurement (`"quantitative"`, `"temporal"`, `"ordinal"`, or
@@ -4558,7 +4558,7 @@ data TextDefWithCondition = TextDefWithCondition
     , fieldTextDefWithCondition :: Maybe Field
     , formatTextDefWithCondition :: Maybe Text
     , timeUnitTextDefWithCondition :: Maybe TimeUnit
-    , textDefWithConditionTypeTextDefWithCondition :: Maybe Type
+    , textDefWithConditionTypeTextDefWithCondition :: Type
     , valueTextDefWithCondition :: Maybe ConditionalValueDefValue
     } deriving (Show)
 
@@ -4617,15 +4617,15 @@ It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
 [geographic projection](projection.html) is applied.
 -}
 data ConditionalPredicateTextFieldDefClass = ConditionalPredicateTextFieldDefClass
-    { testConditionalPredicateTextFieldDefClass :: Maybe LogicalOperandPredicate
-    , valueConditionalPredicateTextFieldDefClass :: Maybe ConditionalValueDefValue
-    , selectionConditionalPredicateTextFieldDefClass :: Maybe SelectionOperand
+    { testConditionalPredicateTextFieldDefClass :: LogicalOperandPredicate
+    , valueConditionalPredicateTextFieldDefClass :: ConditionalValueDefValue
+    , selectionConditionalPredicateTextFieldDefClass :: SelectionOperand
     , aggregateConditionalPredicateTextFieldDefClass :: Maybe AggregateOp
     , binConditionalPredicateTextFieldDefClass :: Maybe Bin
     , fieldConditionalPredicateTextFieldDefClass :: Maybe Field
     , formatConditionalPredicateTextFieldDefClass :: Maybe Text
     , timeUnitConditionalPredicateTextFieldDefClass :: Maybe TimeUnit
-    , conditionalDefTypeConditionalPredicateTextFieldDefClass :: Maybe Type
+    , conditionalDefTypeConditionalPredicateTextFieldDefClass :: Type
     } deriving (Show)
 
 {-| A URL to load upon mouse click.
@@ -4698,7 +4698,7 @@ data DefWithCondition = DefWithCondition
     , conditionDefWithCondition :: Maybe HrefCondition
     , fieldDefWithCondition :: Maybe Field
     , timeUnitDefWithCondition :: Maybe TimeUnit
-    , defWithConditionTypeDefWithCondition :: Maybe Type
+    , defWithConditionTypeDefWithCondition :: Type
     , valueDefWithCondition :: Maybe ConditionalValueDefValue
     } deriving (Show)
 
@@ -4753,14 +4753,14 @@ It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
 [geographic projection](projection.html) is applied.
 -}
 data ConditionalPredicateFieldDefClass = ConditionalPredicateFieldDefClass
-    { testConditionalPredicateFieldDefClass :: Maybe LogicalOperandPredicate
-    , valueConditionalPredicateFieldDefClass :: Maybe ConditionalValueDefValue
-    , selectionConditionalPredicateFieldDefClass :: Maybe SelectionOperand
+    { testConditionalPredicateFieldDefClass :: LogicalOperandPredicate
+    , valueConditionalPredicateFieldDefClass :: ConditionalValueDefValue
+    , selectionConditionalPredicateFieldDefClass :: SelectionOperand
     , aggregateConditionalPredicateFieldDefClass :: Maybe AggregateOp
     , binConditionalPredicateFieldDefClass :: Maybe Bin
     , fieldConditionalPredicateFieldDefClass :: Maybe Field
     , timeUnitConditionalPredicateFieldDefClass :: Maybe TimeUnit
-    , conditionalDefTypeConditionalPredicateFieldDefClass :: Maybe Type
+    , conditionalDefTypeConditionalPredicateFieldDefClass :: Type
     } deriving (Show)
 
 data Order
@@ -4916,8 +4916,8 @@ data XClass = XClass
     , sortXClass :: Maybe SortUnion
     , stackXClass :: Maybe StackOffset
     , timeUnitXClass :: Maybe TimeUnit
-    , defTypeXClass :: Maybe Type
-    , valueXClass :: Maybe ConditionalValueDefValue
+    , defTypeXClass :: Type
+    , valueXClass :: ConditionalValueDefValue
     } deriving (Show)
 
 {-| domain:
@@ -5146,8 +5146,8 @@ data X2Class = X2Class
     , binX2Class :: Maybe Bin
     , fieldX2Class :: Maybe Field
     , timeUnitX2Class :: Maybe TimeUnit
-    , defTypeX2Class :: Maybe Type
-    , valueX2Class :: Maybe ConditionalValueDefValue
+    , defTypeX2Class :: Type
+    , valueX2Class :: ConditionalValueDefValue
     } deriving (Show)
 
 {-| An object that describes mappings between `row` and `column` channels and their field
@@ -5278,21 +5278,21 @@ data Spec = Spec
     { specDataSpec :: Maybe Data
     , descriptionSpec :: Maybe Text
     , heightSpec :: Maybe Float
-    , layerSpec :: Maybe ([LayerSpec])
+    , layerSpec :: [LayerSpec]
     , nameSpec :: Maybe Text
     , resolveSpec :: Maybe Resolve
     , titleSpec :: Maybe Title
     , transformSpec :: Maybe ([Transform])
     , widthSpec :: Maybe Float
-    , encodingSpec :: Maybe Encoding
-    , markSpec :: Maybe AnyMark
+    , encodingSpec :: Encoding
+    , markSpec :: AnyMark
     , projectionSpec :: Maybe Projection
     , selectionSpec :: Maybe (HashMap Text SelectionDef)
-    , facetSpec :: Maybe FacetMapping
-    , specSpec :: Maybe Spec
-    , repeatSpec :: Maybe Repeat
-    , vconcatSpec :: Maybe ([Spec])
-    , hconcatSpec :: Maybe ([Spec])
+    , facetSpec :: FacetMapping
+    , specSpec :: Spec
+    , repeatSpec :: Repeat
+    , vconcatSpec :: [Spec]
+    , hconcatSpec :: [Spec]
     } deriving (Show)
 
 {-| A key-value mapping between encoding channels and definition of fields.
@@ -5467,14 +5467,14 @@ data LayerSpec = LayerSpec
     { layerSpecDataLayerSpec :: Maybe Data
     , descriptionLayerSpec :: Maybe Text
     , heightLayerSpec :: Maybe Float
-    , layerLayerSpec :: Maybe ([LayerSpec])
+    , layerLayerSpec :: [LayerSpec]
     , nameLayerSpec :: Maybe Text
     , resolveLayerSpec :: Maybe Resolve
     , titleLayerSpec :: Maybe Title
     , transformLayerSpec :: Maybe ([Transform])
     , widthLayerSpec :: Maybe Float
-    , encodingLayerSpec :: Maybe Encoding
-    , markLayerSpec :: Maybe AnyMark
+    , encodingLayerSpec :: Encoding
+    , markLayerSpec :: AnyMark
     , projectionLayerSpec :: Maybe Projection
     , selectionLayerSpec :: Maybe (HashMap Text SelectionDef)
     } deriving (Show)
@@ -5505,9 +5505,9 @@ Provide a placeholder name and bind data at runtime.
 -}
 data Data = Data
     { formatData :: Maybe DataFormat
-    , urlData :: Maybe Text
-    , valuesData :: Maybe Values
-    , nameData :: Maybe Text
+    , urlData :: Text
+    , valuesData :: Values
+    , nameData :: Text
     } deriving (Show)
 
 {-| An object that specifies the format for parsing the data file.
@@ -6174,16 +6174,16 @@ The data fields to group by. If not specified, a single group containing all dat
 will be used.
 -}
 data Transform = Transform
-    { filterTransform :: Maybe LogicalOperandPredicate
+    { filterTransform :: LogicalOperandPredicate
     , transformAsTransform :: Maybe Style
-    , calculateTransform :: Maybe Text
+    , calculateTransform :: Text
     , transformDefaultTransform :: Maybe Text
-    , fromTransform :: Maybe LookupData
-    , lookupTransform :: Maybe Text
-    , binTransform :: Maybe Bin
-    , fieldTransform :: Maybe Text
-    , timeUnitTransform :: Maybe TimeUnit
-    , aggregateTransform :: Maybe ([AggregatedFieldDef])
+    , fromTransform :: LookupData
+    , lookupTransform :: Text
+    , binTransform :: Bin
+    , fieldTransform :: Text
+    , timeUnitTransform :: TimeUnit
+    , aggregateTransform :: [AggregatedFieldDef]
     , groupbyTransform :: Maybe ([Text])
     } deriving (Show)
 
@@ -6276,9 +6276,9 @@ instance FromJSON QuickType where
         <*> v .:? "config"
         <*> v .:? "data"
         <*> v .:? "description"
-        <*> v .:? "encoding"
+        <*> v .: "encoding"
         <*> v .:? "height"
-        <*> v .:? "mark"
+        <*> v .: "mark"
         <*> v .:? "name"
         <*> v .:? "padding"
         <*> v .:? "projection"
@@ -6286,13 +6286,13 @@ instance FromJSON QuickType where
         <*> v .:? "title"
         <*> v .:? "transform"
         <*> v .:? "width"
-        <*> v .:? "layer"
+        <*> v .: "layer"
         <*> v .:? "resolve"
-        <*> v .:? "facet"
-        <*> v .:? "spec"
-        <*> v .:? "repeat"
-        <*> v .:? "vconcat"
-        <*> v .:? "hconcat"
+        <*> v .: "facet"
+        <*> v .: "spec"
+        <*> v .: "repeat"
+        <*> v .: "vconcat"
+        <*> v .: "hconcat"
 
 instance ToJSON Autosize where
     toJSON (AutoSizeParamsInAutosize x) = toJSON x
@@ -7243,7 +7243,7 @@ instance FromJSON VGScheme where
     parseJSON (Object v) = VGScheme
         <$> v .:? "count"
         <*> v .:? "extent"
-        <*> v .:? "scheme"
+        <*> v .: "scheme"
         <*> v .:? "step"
 
 instance ToJSON ScaleConfig where
@@ -7483,7 +7483,7 @@ instance FromJSON VGBinding where
     parseJSON (Object v) = VGBinding
         <$> v .:? "element"
         <*> v .: "input"
-        <*> v .:? "options"
+        <*> v .: "options"
         <*> v .:? "max"
         <*> v .:? "min"
         <*> v .:? "step"
@@ -7781,7 +7781,7 @@ instance FromJSON MarkPropDefWithCondition where
         <*> v .:? "scale"
         <*> v .:? "sort"
         <*> v .:? "timeUnit"
-        <*> v .:? "type"
+        <*> v .: "type"
         <*> v .:? "value"
 
 instance ToJSON AggregateOp where
@@ -7882,9 +7882,9 @@ instance ToJSON ConditionalValueDef where
 
 instance FromJSON ConditionalValueDef where
     parseJSON (Object v) = ConditionalValueDef
-        <$> v .:? "test"
+        <$> v .: "test"
         <*> v .: "value"
-        <*> v .:? "selection"
+        <*> v .: "selection"
 
 instance ToJSON Selection where
     toJSON (Selection notSelection andSelection orSelection) =
@@ -7896,9 +7896,9 @@ instance ToJSON Selection where
 
 instance FromJSON Selection where
     parseJSON (Object v) = Selection
-        <$> v .:? "not"
-        <*> v .:? "and"
-        <*> v .:? "or"
+        <$> v .: "not"
+        <*> v .: "and"
+        <*> v .: "or"
 
 instance ToJSON SelectionOperand where
     toJSON (SelectionInSelectionOperand x) = toJSON x
@@ -7924,15 +7924,15 @@ instance ToJSON Predicate where
 
 instance FromJSON Predicate where
     parseJSON (Object v) = Predicate
-        <$> v .:? "not"
-        <*> v .:? "and"
-        <*> v .:? "or"
-        <*> v .:? "equal"
-        <*> v .:? "field"
+        <$> v .: "not"
+        <*> v .: "and"
+        <*> v .: "or"
+        <*> v .: "equal"
+        <*> v .: "field"
         <*> v .:? "timeUnit"
-        <*> v .:? "range"
-        <*> v .:? "oneOf"
-        <*> v .:? "selection"
+        <*> v .: "range"
+        <*> v .: "oneOf"
+        <*> v .: "selection"
 
 instance ToJSON LogicalOperandPredicate where
     toJSON (PredicateInLogicalOperandPredicate x) = toJSON x
@@ -8130,9 +8130,9 @@ instance ToJSON ConditionalPredicateMarkPropFieldDefClass where
 
 instance FromJSON ConditionalPredicateMarkPropFieldDefClass where
     parseJSON (Object v) = ConditionalPredicateMarkPropFieldDefClass
-        <$> v .:? "test"
-        <*> v .:? "value"
-        <*> v .:? "selection"
+        <$> v .: "test"
+        <*> v .: "value"
+        <*> v .: "selection"
         <*> v .:? "aggregate"
         <*> v .:? "bin"
         <*> v .:? "field"
@@ -8140,7 +8140,7 @@ instance FromJSON ConditionalPredicateMarkPropFieldDefClass where
         <*> v .:? "scale"
         <*> v .:? "sort"
         <*> v .:? "timeUnit"
-        <*> v .:? "type"
+        <*> v .: "type"
 
 instance ToJSON Type where
     toJSON QuantitativeType = "quantitative"
@@ -8559,7 +8559,7 @@ instance FromJSON TextDefWithCondition where
         <*> v .:? "field"
         <*> v .:? "format"
         <*> v .:? "timeUnit"
-        <*> v .:? "type"
+        <*> v .: "type"
         <*> v .:? "value"
 
 instance ToJSON TextCondition where
@@ -8586,15 +8586,15 @@ instance ToJSON ConditionalPredicateTextFieldDefClass where
 
 instance FromJSON ConditionalPredicateTextFieldDefClass where
     parseJSON (Object v) = ConditionalPredicateTextFieldDefClass
-        <$> v .:? "test"
-        <*> v .:? "value"
-        <*> v .:? "selection"
+        <$> v .: "test"
+        <*> v .: "value"
+        <*> v .: "selection"
         <*> v .:? "aggregate"
         <*> v .:? "bin"
         <*> v .:? "field"
         <*> v .:? "format"
         <*> v .:? "timeUnit"
-        <*> v .:? "type"
+        <*> v .: "type"
 
 instance ToJSON DefWithCondition where
     toJSON (DefWithCondition aggregateDefWithCondition binDefWithCondition conditionDefWithCondition fieldDefWithCondition timeUnitDefWithCondition defWithConditionTypeDefWithCondition valueDefWithCondition) =
@@ -8615,7 +8615,7 @@ instance FromJSON DefWithCondition where
         <*> v .:? "condition"
         <*> v .:? "field"
         <*> v .:? "timeUnit"
-        <*> v .:? "type"
+        <*> v .: "type"
         <*> v .:? "value"
 
 instance ToJSON HrefCondition where
@@ -8641,14 +8641,14 @@ instance ToJSON ConditionalPredicateFieldDefClass where
 
 instance FromJSON ConditionalPredicateFieldDefClass where
     parseJSON (Object v) = ConditionalPredicateFieldDefClass
-        <$> v .:? "test"
-        <*> v .:? "value"
-        <*> v .:? "selection"
+        <$> v .: "test"
+        <*> v .: "value"
+        <*> v .: "selection"
         <*> v .:? "aggregate"
         <*> v .:? "bin"
         <*> v .:? "field"
         <*> v .:? "timeUnit"
-        <*> v .:? "type"
+        <*> v .: "type"
 
 instance ToJSON Order where
     toJSON (OrderFieldDefArrayInOrder x) = toJSON x
@@ -8703,8 +8703,8 @@ instance FromJSON XClass where
         <*> v .:? "sort"
         <*> v .:? "stack"
         <*> v .:? "timeUnit"
-        <*> v .:? "type"
-        <*> v .:? "value"
+        <*> v .: "type"
+        <*> v .: "value"
 
 instance ToJSON Axis where
     toJSON (Axis domainAxis formatAxis gridAxis labelAngleAxis labelBoundAxis labelFlushAxis labelOverlapAxis labelPaddingAxis labelsAxis maxExtentAxis minExtentAxis offsetAxis orientAxis positionAxis tickCountAxis ticksAxis tickSizeAxis titleAxis titleMaxLengthAxis titlePaddingAxis valuesAxis zindexAxis) =
@@ -8783,8 +8783,8 @@ instance FromJSON X2Class where
         <*> v .:? "bin"
         <*> v .:? "field"
         <*> v .:? "timeUnit"
-        <*> v .:? "type"
-        <*> v .:? "value"
+        <*> v .: "type"
+        <*> v .: "value"
 
 instance ToJSON FacetMapping where
     toJSON (FacetMapping columnFacetMapping rowFacetMapping) =
@@ -8826,21 +8826,21 @@ instance FromJSON Spec where
         <$> v .:? "data"
         <*> v .:? "description"
         <*> v .:? "height"
-        <*> v .:? "layer"
+        <*> v .: "layer"
         <*> v .:? "name"
         <*> v .:? "resolve"
         <*> v .:? "title"
         <*> v .:? "transform"
         <*> v .:? "width"
-        <*> v .:? "encoding"
-        <*> v .:? "mark"
+        <*> v .: "encoding"
+        <*> v .: "mark"
         <*> v .:? "projection"
         <*> v .:? "selection"
-        <*> v .:? "facet"
-        <*> v .:? "spec"
-        <*> v .:? "repeat"
-        <*> v .:? "vconcat"
-        <*> v .:? "hconcat"
+        <*> v .: "facet"
+        <*> v .: "spec"
+        <*> v .: "repeat"
+        <*> v .: "vconcat"
+        <*> v .: "hconcat"
 
 instance ToJSON Encoding where
     toJSON (Encoding colorEncoding detailEncoding hrefEncoding opacityEncoding orderEncoding shapeEncoding sizeEncoding encodingTextEncoding tooltipEncoding xEncoding x2Encoding yEncoding y2Encoding) =
@@ -8899,14 +8899,14 @@ instance FromJSON LayerSpec where
         <$> v .:? "data"
         <*> v .:? "description"
         <*> v .:? "height"
-        <*> v .:? "layer"
+        <*> v .: "layer"
         <*> v .:? "name"
         <*> v .:? "resolve"
         <*> v .:? "title"
         <*> v .:? "transform"
         <*> v .:? "width"
-        <*> v .:? "encoding"
-        <*> v .:? "mark"
+        <*> v .: "encoding"
+        <*> v .: "mark"
         <*> v .:? "projection"
         <*> v .:? "selection"
 
@@ -8922,9 +8922,9 @@ instance ToJSON Data where
 instance FromJSON Data where
     parseJSON (Object v) = Data
         <$> v .:? "format"
-        <*> v .:? "url"
-        <*> v .:? "values"
-        <*> v .:? "name"
+        <*> v .: "url"
+        <*> v .: "values"
+        <*> v .: "name"
 
 instance ToJSON DataFormat where
     toJSON (DataFormat parseDataFormat dataFormatTypeDataFormat propertyDataFormat featureDataFormat meshDataFormat) =
@@ -9320,16 +9320,16 @@ instance ToJSON Transform where
 
 instance FromJSON Transform where
     parseJSON (Object v) = Transform
-        <$> v .:? "filter"
+        <$> v .: "filter"
         <*> v .:? "as"
-        <*> v .:? "calculate"
+        <*> v .: "calculate"
         <*> v .:? "default"
-        <*> v .:? "from"
-        <*> v .:? "lookup"
-        <*> v .:? "bin"
-        <*> v .:? "field"
-        <*> v .:? "timeUnit"
-        <*> v .:? "aggregate"
+        <*> v .: "from"
+        <*> v .: "lookup"
+        <*> v .: "bin"
+        <*> v .: "field"
+        <*> v .: "timeUnit"
+        <*> v .: "aggregate"
         <*> v .:? "groupby"
 
 instance ToJSON AggregatedFieldDef where
diff --git a/head/schema-java/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/Anyof.java b/head/schema-java/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/Anyof.java
new file mode 100644
index 0000000..500bdc2
--- /dev/null
+++ b/head/schema-java/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/Anyof.java
@@ -0,0 +1,18 @@
+package io.quicktype;
+
+import com.fasterxml.jackson.annotation.*;
+
+public class Anyof {
+    private String name;
+    private String size;
+
+    @JsonProperty("name")
+    public String getName() { return name; }
+    @JsonProperty("name")
+    public void setName(String value) { this.name = value; }
+
+    @JsonProperty("size")
+    public String getSize() { return size; }
+    @JsonProperty("size")
+    public void setSize(String value) { this.size = value; }
+}
diff --git a/head/schema-java/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/Converter.java b/head/schema-java/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/Converter.java
new file mode 100644
index 0000000..a8eb236
--- /dev/null
+++ b/head/schema-java/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/Converter.java
@@ -0,0 +1,101 @@
+// To use this code, add the following Maven dependency to your project:
+//
+//
+//     com.fasterxml.jackson.core     : jackson-databind          : 2.9.0
+//     com.fasterxml.jackson.datatype : jackson-datatype-jsr310   : 2.9.0
+//
+// Import this package:
+//
+//     import io.quicktype.Converter;
+//
+// Then you can deserialize a JSON string with
+//
+//     TopLevel data = Converter.fromJsonString(jsonString);
+
+package io.quicktype;
+
+import java.io.IOException;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import java.util.*;
+import java.time.LocalDate;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.temporal.ChronoField;
+
+public class Converter {
+    // Date-time helpers
+
+    private static final DateTimeFormatter DATE_TIME_FORMATTER = new DateTimeFormatterBuilder()
+            .appendOptional(DateTimeFormatter.ISO_DATE_TIME)
+            .appendOptional(DateTimeFormatter.ISO_OFFSET_DATE_TIME)
+            .appendOptional(DateTimeFormatter.ISO_INSTANT)
+            .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SX"))
+            .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ssX"))
+            .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
+            .toFormatter()
+            .withZone(ZoneOffset.UTC);
+
+    public static OffsetDateTime parseDateTimeString(String str) {
+        return ZonedDateTime.from(Converter.DATE_TIME_FORMATTER.parse(str)).toOffsetDateTime();
+    }
+
+    private static final DateTimeFormatter TIME_FORMATTER = new DateTimeFormatterBuilder()
+            .appendOptional(DateTimeFormatter.ISO_TIME)
+            .appendOptional(DateTimeFormatter.ISO_OFFSET_TIME)
+            .parseDefaulting(ChronoField.YEAR, 2020)
+            .parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
+            .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
+            .toFormatter()
+            .withZone(ZoneOffset.UTC);
+
+    public static OffsetTime parseTimeString(String str) {
+        return ZonedDateTime.from(Converter.TIME_FORMATTER.parse(str)).toOffsetDateTime().toOffsetTime();
+    }
+    // Serialize/deserialize helpers
+
+    public static TopLevel fromJsonString(String json) throws IOException {
+        return getObjectReader().readValue(json);
+    }
+
+    public static String toJsonString(TopLevel obj) throws JsonProcessingException {
+        return getObjectWriter().writeValueAsString(obj);
+    }
+
+    private static ObjectReader reader;
+    private static ObjectWriter writer;
+
+    private static void instantiateMapper() {
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.findAndRegisterModules();
+        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
+        SimpleModule module = new SimpleModule();
+        module.addDeserializer(OffsetDateTime.class, new JsonDeserializer<OffsetDateTime>() {
+            @Override
+            public OffsetDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+                String value = jsonParser.getText();
+                return Converter.parseDateTimeString(value);
+            }
+        });
+        mapper.registerModule(module);
+        reader = mapper.readerFor(TopLevel.class);
+        writer = mapper.writerFor(TopLevel.class);
+    }
+
+    private static ObjectReader getObjectReader() {
+        if (reader == null) instantiateMapper();
+        return reader;
+    }
+
+    private static ObjectWriter getObjectWriter() {
+        if (writer == null) instantiateMapper();
+        return writer;
+    }
+}
diff --git a/head/schema-java/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/TopLevel.java b/head/schema-java/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/TopLevel.java
new file mode 100644
index 0000000..b180d63
--- /dev/null
+++ b/head/schema-java/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/TopLevel.java
@@ -0,0 +1,12 @@
+package io.quicktype;
+
+import com.fasterxml.jackson.annotation.*;
+
+public class TopLevel {
+    private Anyof anyof;
+
+    @JsonProperty("anyof")
+    public Anyof getAnyof() { return anyof; }
+    @JsonProperty("anyof")
+    public void setAnyof(Anyof value) { this.anyof = value; }
+}
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/AnyMark.java b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/AnyMark.java
index 7ffb7ef..ff16a90 100644
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/AnyMark.java
+++ b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/AnyMark.java
@@ -24,8 +24,6 @@ public class AnyMark {
         public AnyMark deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
             AnyMark value = new AnyMark();
             switch (jsonParser.currentToken()) {
-                case VALUE_NULL:
-                    break;
                 case VALUE_STRING:
                     String string = jsonParser.readValueAs(String.class);
                     try {
@@ -54,7 +52,7 @@ public class AnyMark {
                 jsonGenerator.writeObject(obj.enumValue);
                 return;
             }
-            jsonGenerator.writeNull();
+            throw new IOException("AnyMark must not be null");
         }
     }
 }
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Bin.java b/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Bin.java
deleted file mode 100644
index f2b4b13..0000000
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Bin.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package io.quicktype;
-
-import java.io.IOException;
-import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.annotation.*;
-import com.fasterxml.jackson.core.type.*;
-
-@JsonDeserialize(using = Bin.Deserializer.class)
-@JsonSerialize(using = Bin.Serializer.class)
-public class Bin {
-    public Boolean boolValue;
-    public BinParams binParamsValue;
-
-    static class Deserializer extends JsonDeserializer<Bin> {
-        @Override
-        public Bin deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            Bin value = new Bin();
-            switch (jsonParser.currentToken()) {
-                case VALUE_NULL:
-                    break;
-                case VALUE_TRUE:
-                case VALUE_FALSE:
-                    value.boolValue = jsonParser.readValueAs(Boolean.class);
-                    break;
-                case START_OBJECT:
-                    value.binParamsValue = jsonParser.readValueAs(BinParams.class);
-                    break;
-                default: throw new IOException("Cannot deserialize Bin");
-            }
-            return value;
-        }
-    }
-
-    static class Serializer extends JsonSerializer<Bin> {
-        @Override
-        public void serialize(Bin obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-            if (obj.boolValue != null) {
-                jsonGenerator.writeObject(obj.boolValue);
-                return;
-            }
-            if (obj.binParamsValue != null) {
-                jsonGenerator.writeObject(obj.binParamsValue);
-                return;
-            }
-            jsonGenerator.writeNull();
-        }
-    }
-}
diff --git a/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ColorBin.java b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ColorBin.java
new file mode 100644
index 0000000..ba25f2a
--- /dev/null
+++ b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ColorBin.java
@@ -0,0 +1,50 @@
+package io.quicktype;
+
+import java.io.IOException;
+import java.io.IOException;
+import com.fasterxml.jackson.core.*;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.annotation.*;
+import com.fasterxml.jackson.core.type.*;
+
+@JsonDeserialize(using = ColorBin.Deserializer.class)
+@JsonSerialize(using = ColorBin.Serializer.class)
+public class ColorBin {
+    public Boolean boolValue;
+    public BinParams binParamsValue;
+
+    static class Deserializer extends JsonDeserializer<ColorBin> {
+        @Override
+        public ColorBin deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            ColorBin value = new ColorBin();
+            switch (jsonParser.currentToken()) {
+                case VALUE_NULL:
+                    break;
+                case VALUE_TRUE:
+                case VALUE_FALSE:
+                    value.boolValue = jsonParser.readValueAs(Boolean.class);
+                    break;
+                case START_OBJECT:
+                    value.binParamsValue = jsonParser.readValueAs(BinParams.class);
+                    break;
+                default: throw new IOException("Cannot deserialize ColorBin");
+            }
+            return value;
+        }
+    }
+
+    static class Serializer extends JsonSerializer<ColorBin> {
+        @Override
+        public void serialize(ColorBin obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+            if (obj.boolValue != null) {
+                jsonGenerator.writeObject(obj.boolValue);
+                return;
+            }
+            if (obj.binParamsValue != null) {
+                jsonGenerator.writeObject(obj.binParamsValue);
+                return;
+            }
+            jsonGenerator.writeNull();
+        }
+    }
+}
diff --git a/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ColorValue.java b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ColorValue.java
new file mode 100644
index 0000000..bb6fb5b
--- /dev/null
+++ b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ColorValue.java
@@ -0,0 +1,66 @@
+package io.quicktype;
+
+import java.io.IOException;
+import java.io.IOException;
+import com.fasterxml.jackson.core.*;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.annotation.*;
+import com.fasterxml.jackson.core.type.*;
+
+/**
+ * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
+ * `0` to `1` for opacity).
+ *
+ * A constant value in visual domain.
+ */
+@JsonDeserialize(using = ColorValue.Deserializer.class)
+@JsonSerialize(using = ColorValue.Serializer.class)
+public class ColorValue {
+    public Double doubleValue;
+    public Boolean boolValue;
+    public String stringValue;
+
+    static class Deserializer extends JsonDeserializer<ColorValue> {
+        @Override
+        public ColorValue deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            ColorValue value = new ColorValue();
+            switch (jsonParser.currentToken()) {
+                case VALUE_NULL:
+                    break;
+                case VALUE_NUMBER_INT:
+                case VALUE_NUMBER_FLOAT:
+                    value.doubleValue = jsonParser.readValueAs(Double.class);
+                    break;
+                case VALUE_TRUE:
+                case VALUE_FALSE:
+                    value.boolValue = jsonParser.readValueAs(Boolean.class);
+                    break;
+                case VALUE_STRING:
+                    String string = jsonParser.readValueAs(String.class);
+                    value.stringValue = string;
+                    break;
+                default: throw new IOException("Cannot deserialize ColorValue");
+            }
+            return value;
+        }
+    }
+
+    static class Serializer extends JsonSerializer<ColorValue> {
+        @Override
+        public void serialize(ColorValue obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+            if (obj.doubleValue != null) {
+                jsonGenerator.writeObject(obj.doubleValue);
+                return;
+            }
+            if (obj.boolValue != null) {
+                jsonGenerator.writeObject(obj.boolValue);
+                return;
+            }
+            if (obj.stringValue != null) {
+                jsonGenerator.writeObject(obj.stringValue);
+                return;
+            }
+            jsonGenerator.writeNull();
+        }
+    }
+}
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateFieldDefClass.java b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateFieldDefClass.java
index 0ee72f6..d883001 100644
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateFieldDefClass.java
+++ b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateFieldDefClass.java
@@ -3,37 +3,37 @@ package io.quicktype;
 import com.fasterxml.jackson.annotation.*;
 
 public class ConditionalPredicateFieldDefClass {
-    private ConditionalValueDefLogicalOperandPredicate test;
-    private ConditionalPredicateValueDefValue value;
-    private ConditionalValueDefSelectionOperand selection;
+    private LogicalOperandPredicate test;
+    private ConditionalValueDefValue value;
+    private SelectionOperand selection;
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private Field field;
     private TimeUnit timeUnit;
     private Type type;
 
     @JsonProperty("test")
-    public ConditionalValueDefLogicalOperandPredicate getTest() { return test; }
+    public LogicalOperandPredicate getTest() { return test; }
     @JsonProperty("test")
-    public void setTest(ConditionalValueDefLogicalOperandPredicate value) { this.test = value; }
+    public void setTest(LogicalOperandPredicate value) { this.test = value; }
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
     @JsonProperty("value")
-    public ConditionalPredicateValueDefValue getValue() { return value; }
+    public ConditionalValueDefValue getValue() { return value; }
     @JsonProperty("value")
-    public void setValue(ConditionalPredicateValueDefValue value) { this.value = value; }
+    public void setValue(ConditionalValueDefValue value) { this.value = value; }
 
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
     @JsonProperty("selection")
-    public ConditionalValueDefSelectionOperand getSelection() { return selection; }
+    public SelectionOperand getSelection() { return selection; }
     @JsonProperty("selection")
-    public void setSelection(ConditionalValueDefSelectionOperand value) { this.selection = value; }
+    public void setSelection(SelectionOperand value) { this.selection = value; }
 
     /**
      * Aggregation function for the field
@@ -54,9 +54,9 @@ public class ConditionalPredicateFieldDefClass {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * __Required.__ A string defining the name of the field from which to pull a data value
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateMarkPropFieldDefClass.java b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateMarkPropFieldDefClass.java
index bd46210..cf72cce 100644
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateMarkPropFieldDefClass.java
+++ b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateMarkPropFieldDefClass.java
@@ -3,11 +3,11 @@ package io.quicktype;
 import com.fasterxml.jackson.annotation.*;
 
 public class ConditionalPredicateMarkPropFieldDefClass {
-    private ConditionalValueDefLogicalOperandPredicate test;
-    private ConditionalPredicateValueDefValue value;
-    private ConditionalValueDefSelectionOperand selection;
+    private LogicalOperandPredicate test;
+    private ConditionalValueDefValue value;
+    private SelectionOperand selection;
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private Field field;
     private Legend legend;
     private Scale scale;
@@ -16,27 +16,27 @@ public class ConditionalPredicateMarkPropFieldDefClass {
     private Type type;
 
     @JsonProperty("test")
-    public ConditionalValueDefLogicalOperandPredicate getTest() { return test; }
+    public LogicalOperandPredicate getTest() { return test; }
     @JsonProperty("test")
-    public void setTest(ConditionalValueDefLogicalOperandPredicate value) { this.test = value; }
+    public void setTest(LogicalOperandPredicate value) { this.test = value; }
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
     @JsonProperty("value")
-    public ConditionalPredicateValueDefValue getValue() { return value; }
+    public ConditionalValueDefValue getValue() { return value; }
     @JsonProperty("value")
-    public void setValue(ConditionalPredicateValueDefValue value) { this.value = value; }
+    public void setValue(ConditionalValueDefValue value) { this.value = value; }
 
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
     @JsonProperty("selection")
-    public ConditionalValueDefSelectionOperand getSelection() { return selection; }
+    public SelectionOperand getSelection() { return selection; }
     @JsonProperty("selection")
-    public void setSelection(ConditionalValueDefSelectionOperand value) { this.selection = value; }
+    public void setSelection(SelectionOperand value) { this.selection = value; }
 
     /**
      * Aggregation function for the field
@@ -57,9 +57,9 @@ public class ConditionalPredicateMarkPropFieldDefClass {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * __Required.__ A string defining the name of the field from which to pull a data value
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateTextFieldDefClass.java b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateTextFieldDefClass.java
index eafdc1a..8141189 100644
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateTextFieldDefClass.java
+++ b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateTextFieldDefClass.java
@@ -3,38 +3,38 @@ package io.quicktype;
 import com.fasterxml.jackson.annotation.*;
 
 public class ConditionalPredicateTextFieldDefClass {
-    private ConditionalValueDefLogicalOperandPredicate test;
-    private ConditionalPredicateValueDefValue value;
-    private ConditionalValueDefSelectionOperand selection;
+    private LogicalOperandPredicate test;
+    private ConditionalValueDefValue value;
+    private SelectionOperand selection;
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private Field field;
     private String format;
     private TimeUnit timeUnit;
     private Type type;
 
     @JsonProperty("test")
-    public ConditionalValueDefLogicalOperandPredicate getTest() { return test; }
+    public LogicalOperandPredicate getTest() { return test; }
     @JsonProperty("test")
-    public void setTest(ConditionalValueDefLogicalOperandPredicate value) { this.test = value; }
+    public void setTest(LogicalOperandPredicate value) { this.test = value; }
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
     @JsonProperty("value")
-    public ConditionalPredicateValueDefValue getValue() { return value; }
+    public ConditionalValueDefValue getValue() { return value; }
     @JsonProperty("value")
-    public void setValue(ConditionalPredicateValueDefValue value) { this.value = value; }
+    public void setValue(ConditionalValueDefValue value) { this.value = value; }
 
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
     @JsonProperty("selection")
-    public ConditionalValueDefSelectionOperand getSelection() { return selection; }
+    public SelectionOperand getSelection() { return selection; }
     @JsonProperty("selection")
-    public void setSelection(ConditionalValueDefSelectionOperand value) { this.selection = value; }
+    public void setSelection(SelectionOperand value) { this.selection = value; }
 
     /**
      * Aggregation function for the field
@@ -55,9 +55,9 @@ public class ConditionalPredicateTextFieldDefClass {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * __Required.__ A string defining the name of the field from which to pull a data value
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateValueDefValue.java b/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateValueDefValue.java
deleted file mode 100644
index fe41fbe..0000000
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateValueDefValue.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package io.quicktype;
-
-import java.io.IOException;
-import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.annotation.*;
-import com.fasterxml.jackson.core.type.*;
-
-/**
- * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
- * `0` to `1` for opacity).
- *
- * A constant value in visual domain.
- */
-@JsonDeserialize(using = ConditionalPredicateValueDefValue.Deserializer.class)
-@JsonSerialize(using = ConditionalPredicateValueDefValue.Serializer.class)
-public class ConditionalPredicateValueDefValue {
-    public Double doubleValue;
-    public Boolean boolValue;
-    public String stringValue;
-
-    static class Deserializer extends JsonDeserializer<ConditionalPredicateValueDefValue> {
-        @Override
-        public ConditionalPredicateValueDefValue deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            ConditionalPredicateValueDefValue value = new ConditionalPredicateValueDefValue();
-            switch (jsonParser.currentToken()) {
-                case VALUE_NULL:
-                    break;
-                case VALUE_NUMBER_INT:
-                case VALUE_NUMBER_FLOAT:
-                    value.doubleValue = jsonParser.readValueAs(Double.class);
-                    break;
-                case VALUE_TRUE:
-                case VALUE_FALSE:
-                    value.boolValue = jsonParser.readValueAs(Boolean.class);
-                    break;
-                case VALUE_STRING:
-                    String string = jsonParser.readValueAs(String.class);
-                    value.stringValue = string;
-                    break;
-                default: throw new IOException("Cannot deserialize ConditionalPredicateValueDefValue");
-            }
-            return value;
-        }
-    }
-
-    static class Serializer extends JsonSerializer<ConditionalPredicateValueDefValue> {
-        @Override
-        public void serialize(ConditionalPredicateValueDefValue obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-            if (obj.doubleValue != null) {
-                jsonGenerator.writeObject(obj.doubleValue);
-                return;
-            }
-            if (obj.boolValue != null) {
-                jsonGenerator.writeObject(obj.boolValue);
-                return;
-            }
-            if (obj.stringValue != null) {
-                jsonGenerator.writeObject(obj.stringValue);
-                return;
-            }
-            jsonGenerator.writeNull();
-        }
-    }
-}
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDef.java b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDef.java
index d11e6b0..4853170 100644
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDef.java
+++ b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDef.java
@@ -3,14 +3,14 @@ package io.quicktype;
 import com.fasterxml.jackson.annotation.*;
 
 public class ConditionalValueDef {
-    private ConditionalValueDefLogicalOperandPredicate test;
+    private LogicalOperandPredicate test;
     private ConditionalValueDefValue value;
-    private ConditionalValueDefSelectionOperand selection;
+    private SelectionOperand selection;
 
     @JsonProperty("test")
-    public ConditionalValueDefLogicalOperandPredicate getTest() { return test; }
+    public LogicalOperandPredicate getTest() { return test; }
     @JsonProperty("test")
-    public void setTest(ConditionalValueDefLogicalOperandPredicate value) { this.test = value; }
+    public void setTest(LogicalOperandPredicate value) { this.test = value; }
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
@@ -26,7 +26,7 @@ public class ConditionalValueDef {
      * selections](selection.html#compose).
      */
     @JsonProperty("selection")
-    public ConditionalValueDefSelectionOperand getSelection() { return selection; }
+    public SelectionOperand getSelection() { return selection; }
     @JsonProperty("selection")
-    public void setSelection(ConditionalValueDefSelectionOperand value) { this.selection = value; }
+    public void setSelection(SelectionOperand value) { this.selection = value; }
 }
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDefLogicalOperandPredicate.java b/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDefLogicalOperandPredicate.java
deleted file mode 100644
index f4bf576..0000000
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDefLogicalOperandPredicate.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package io.quicktype;
-
-import java.io.IOException;
-import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.annotation.*;
-import com.fasterxml.jackson.core.type.*;
-
-/**
- * The `filter` property must be one of the predicate definitions:
- * (1) an [expression](types.html#expression) string,
- * where `datum` can be used to refer to the current data object;
- * (2) one of the field predicates: [equal predicate](filter.html#equal-predicate);
- * [range predicate](filter.html#range-predicate), [one-of
- * predicate](filter.html#one-of-predicate);
- * (3) a [selection predicate](filter.html#selection-predicate);
- * or (4) a logical operand that combines (1), (2), or (3).
- */
-@JsonDeserialize(using = ConditionalValueDefLogicalOperandPredicate.Deserializer.class)
-@JsonSerialize(using = ConditionalValueDefLogicalOperandPredicate.Serializer.class)
-public class ConditionalValueDefLogicalOperandPredicate {
-    public Predicate predicateValue;
-    public String stringValue;
-
-    static class Deserializer extends JsonDeserializer<ConditionalValueDefLogicalOperandPredicate> {
-        @Override
-        public ConditionalValueDefLogicalOperandPredicate deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            ConditionalValueDefLogicalOperandPredicate value = new ConditionalValueDefLogicalOperandPredicate();
-            switch (jsonParser.currentToken()) {
-                case VALUE_NULL:
-                    break;
-                case VALUE_STRING:
-                    String string = jsonParser.readValueAs(String.class);
-                    value.stringValue = string;
-                    break;
-                case START_OBJECT:
-                    value.predicateValue = jsonParser.readValueAs(Predicate.class);
-                    break;
-                default: throw new IOException("Cannot deserialize ConditionalValueDefLogicalOperandPredicate");
-            }
-            return value;
-        }
-    }
-
-    static class Serializer extends JsonSerializer<ConditionalValueDefLogicalOperandPredicate> {
-        @Override
-        public void serialize(ConditionalValueDefLogicalOperandPredicate obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-            if (obj.predicateValue != null) {
-                jsonGenerator.writeObject(obj.predicateValue);
-                return;
-            }
-            if (obj.stringValue != null) {
-                jsonGenerator.writeObject(obj.stringValue);
-                return;
-            }
-            jsonGenerator.writeNull();
-        }
-    }
-}
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDefSelectionOperand.java b/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDefSelectionOperand.java
deleted file mode 100644
index 3ee477d..0000000
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDefSelectionOperand.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package io.quicktype;
-
-import java.io.IOException;
-import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.annotation.*;
-import com.fasterxml.jackson.core.type.*;
-
-/**
- * Filter using a selection name.
- *
- * A [selection name](selection.html), or a series of [composed
- * selections](selection.html#compose).
- */
-@JsonDeserialize(using = ConditionalValueDefSelectionOperand.Deserializer.class)
-@JsonSerialize(using = ConditionalValueDefSelectionOperand.Serializer.class)
-public class ConditionalValueDefSelectionOperand {
-    public Selection selectionValue;
-    public String stringValue;
-
-    static class Deserializer extends JsonDeserializer<ConditionalValueDefSelectionOperand> {
-        @Override
-        public ConditionalValueDefSelectionOperand deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            ConditionalValueDefSelectionOperand value = new ConditionalValueDefSelectionOperand();
-            switch (jsonParser.currentToken()) {
-                case VALUE_NULL:
-                    break;
-                case VALUE_STRING:
-                    String string = jsonParser.readValueAs(String.class);
-                    value.stringValue = string;
-                    break;
-                case START_OBJECT:
-                    value.selectionValue = jsonParser.readValueAs(Selection.class);
-                    break;
-                default: throw new IOException("Cannot deserialize ConditionalValueDefSelectionOperand");
-            }
-            return value;
-        }
-    }
-
-    static class Serializer extends JsonSerializer<ConditionalValueDefSelectionOperand> {
-        @Override
-        public void serialize(ConditionalValueDefSelectionOperand obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-            if (obj.selectionValue != null) {
-                jsonGenerator.writeObject(obj.selectionValue);
-                return;
-            }
-            if (obj.stringValue != null) {
-                jsonGenerator.writeObject(obj.stringValue);
-                return;
-            }
-            jsonGenerator.writeNull();
-        }
-    }
-}
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/DefWithCondition.java b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/DefWithCondition.java
index d044c42..19c0bbb 100644
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/DefWithCondition.java
+++ b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/DefWithCondition.java
@@ -21,12 +21,12 @@ import java.util.List;
  */
 public class DefWithCondition {
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private HrefCondition condition;
     private Field field;
     private TimeUnit timeUnit;
     private Type type;
-    private ConditionalPredicateValueDefValue value;
+    private ColorValue value;
 
     /**
      * Aggregation function for the field
@@ -47,9 +47,9 @@ public class DefWithCondition {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * One or more value definition(s) with a selection predicate.
@@ -108,7 +108,7 @@ public class DefWithCondition {
      * A constant value in visual domain.
      */
     @JsonProperty("value")
-    public ConditionalPredicateValueDefValue getValue() { return value; }
+    public ColorValue getValue() { return value; }
     @JsonProperty("value")
-    public void setValue(ConditionalPredicateValueDefValue value) { this.value = value; }
+    public void setValue(ColorValue value) { this.value = value; }
 }
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/DomainUnion.java b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/DomainUnion.java
index e70f578..0f19e22 100644
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/DomainUnion.java
+++ b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/DomainUnion.java
@@ -29,7 +29,7 @@ import java.util.List;
 @JsonDeserialize(using = DomainUnion.Deserializer.class)
 @JsonSerialize(using = DomainUnion.Serializer.class)
 public class DomainUnion {
-    public List<OneOfElement> unionArrayValue;
+    public List<Equal> unionArrayValue;
     public DomainClass domainClassValue;
     public Domain enumValue;
 
@@ -49,7 +49,7 @@ public class DomainUnion {
                     }
                     break;
                 case START_ARRAY:
-                    value.unionArrayValue = jsonParser.readValueAs(new TypeReference<List<OneOfElement>>() {});
+                    value.unionArrayValue = jsonParser.readValueAs(new TypeReference<List<Equal>>() {});
                     break;
                 case START_OBJECT:
                     value.domainClassValue = jsonParser.readValueAs(DomainClass.class);
diff --git a/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Equal.java b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Equal.java
new file mode 100644
index 0000000..9254aa8
--- /dev/null
+++ b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Equal.java
@@ -0,0 +1,69 @@
+package io.quicktype;
+
+import java.io.IOException;
+import java.io.IOException;
+import com.fasterxml.jackson.core.*;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.annotation.*;
+import com.fasterxml.jackson.core.type.*;
+
+/**
+ * The value that the field should be equal to.
+ */
+@JsonDeserialize(using = Equal.Deserializer.class)
+@JsonSerialize(using = Equal.Serializer.class)
+public class Equal {
+    public Double doubleValue;
+    public Boolean boolValue;
+    public DateTime dateTimeValue;
+    public String stringValue;
+
+    static class Deserializer extends JsonDeserializer<Equal> {
+        @Override
+        public Equal deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            Equal value = new Equal();
+            switch (jsonParser.currentToken()) {
+                case VALUE_NUMBER_INT:
+                case VALUE_NUMBER_FLOAT:
+                    value.doubleValue = jsonParser.readValueAs(Double.class);
+                    break;
+                case VALUE_TRUE:
+                case VALUE_FALSE:
+                    value.boolValue = jsonParser.readValueAs(Boolean.class);
+                    break;
+                case VALUE_STRING:
+                    String string = jsonParser.readValueAs(String.class);
+                    value.stringValue = string;
+                    break;
+                case START_OBJECT:
+                    value.dateTimeValue = jsonParser.readValueAs(DateTime.class);
+                    break;
+                default: throw new IOException("Cannot deserialize Equal");
+            }
+            return value;
+        }
+    }
+
+    static class Serializer extends JsonSerializer<Equal> {
+        @Override
+        public void serialize(Equal obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+            if (obj.doubleValue != null) {
+                jsonGenerator.writeObject(obj.doubleValue);
+                return;
+            }
+            if (obj.boolValue != null) {
+                jsonGenerator.writeObject(obj.boolValue);
+                return;
+            }
+            if (obj.dateTimeValue != null) {
+                jsonGenerator.writeObject(obj.dateTimeValue);
+                return;
+            }
+            if (obj.stringValue != null) {
+                jsonGenerator.writeObject(obj.stringValue);
+                return;
+            }
+            throw new IOException("Equal must not be null");
+        }
+    }
+}
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/EqualUnion.java b/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/EqualUnion.java
deleted file mode 100644
index cde8d77..0000000
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/EqualUnion.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package io.quicktype;
-
-import java.io.IOException;
-import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.annotation.*;
-import com.fasterxml.jackson.core.type.*;
-
-/**
- * The value that the field should be equal to.
- */
-@JsonDeserialize(using = EqualUnion.Deserializer.class)
-@JsonSerialize(using = EqualUnion.Serializer.class)
-public class EqualUnion {
-    public Double doubleValue;
-    public Boolean boolValue;
-    public DateTime dateTimeValue;
-    public String stringValue;
-
-    static class Deserializer extends JsonDeserializer<EqualUnion> {
-        @Override
-        public EqualUnion deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            EqualUnion value = new EqualUnion();
-            switch (jsonParser.currentToken()) {
-                case VALUE_NULL:
-                    break;
-                case VALUE_NUMBER_INT:
-                case VALUE_NUMBER_FLOAT:
-                    value.doubleValue = jsonParser.readValueAs(Double.class);
-                    break;
-                case VALUE_TRUE:
-                case VALUE_FALSE:
-                    value.boolValue = jsonParser.readValueAs(Boolean.class);
-                    break;
-                case VALUE_STRING:
-                    String string = jsonParser.readValueAs(String.class);
-                    value.stringValue = string;
-                    break;
-                case START_OBJECT:
-                    value.dateTimeValue = jsonParser.readValueAs(DateTime.class);
-                    break;
-                default: throw new IOException("Cannot deserialize EqualUnion");
-            }
-            return value;
-        }
-    }
-
-    static class Serializer extends JsonSerializer<EqualUnion> {
-        @Override
-        public void serialize(EqualUnion obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-            if (obj.doubleValue != null) {
-                jsonGenerator.writeObject(obj.doubleValue);
-                return;
-            }
-            if (obj.boolValue != null) {
-                jsonGenerator.writeObject(obj.boolValue);
-                return;
-            }
-            if (obj.dateTimeValue != null) {
-                jsonGenerator.writeObject(obj.dateTimeValue);
-                return;
-            }
-            if (obj.stringValue != null) {
-                jsonGenerator.writeObject(obj.stringValue);
-                return;
-            }
-            jsonGenerator.writeNull();
-        }
-    }
-}
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/FacetFieldDef.java b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/FacetFieldDef.java
index ce6a490..6a4b68b 100644
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/FacetFieldDef.java
+++ b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/FacetFieldDef.java
@@ -9,7 +9,7 @@ import com.fasterxml.jackson.annotation.*;
  */
 public class FacetFieldDef {
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private Field field;
     private Header header;
     private SortEnum sort;
@@ -35,9 +35,9 @@ public class FacetFieldDef {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * __Required.__ A string defining the name of the field from which to pull a data value
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/FieldDef.java b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/FieldDef.java
index 46826ea..ed0f44b 100644
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/FieldDef.java
+++ b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/FieldDef.java
@@ -7,7 +7,7 @@ import com.fasterxml.jackson.annotation.*;
  */
 public class FieldDef {
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private Field field;
     private TimeUnit timeUnit;
     private Type type;
@@ -31,9 +31,9 @@ public class FieldDef {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * __Required.__ A string defining the name of the field from which to pull a data value
diff --git a/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/LogicalOperandPredicate.java b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/LogicalOperandPredicate.java
new file mode 100644
index 0000000..9291af2
--- /dev/null
+++ b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/LogicalOperandPredicate.java
@@ -0,0 +1,58 @@
+package io.quicktype;
+
+import java.io.IOException;
+import java.io.IOException;
+import com.fasterxml.jackson.core.*;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.annotation.*;
+import com.fasterxml.jackson.core.type.*;
+
+/**
+ * The `filter` property must be one of the predicate definitions:
+ * (1) an [expression](types.html#expression) string,
+ * where `datum` can be used to refer to the current data object;
+ * (2) one of the field predicates: [equal predicate](filter.html#equal-predicate);
+ * [range predicate](filter.html#range-predicate), [one-of
+ * predicate](filter.html#one-of-predicate);
+ * (3) a [selection predicate](filter.html#selection-predicate);
+ * or (4) a logical operand that combines (1), (2), or (3).
+ */
+@JsonDeserialize(using = LogicalOperandPredicate.Deserializer.class)
+@JsonSerialize(using = LogicalOperandPredicate.Serializer.class)
+public class LogicalOperandPredicate {
+    public Predicate predicateValue;
+    public String stringValue;
+
+    static class Deserializer extends JsonDeserializer<LogicalOperandPredicate> {
+        @Override
+        public LogicalOperandPredicate deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            LogicalOperandPredicate value = new LogicalOperandPredicate();
+            switch (jsonParser.currentToken()) {
+                case VALUE_STRING:
+                    String string = jsonParser.readValueAs(String.class);
+                    value.stringValue = string;
+                    break;
+                case START_OBJECT:
+                    value.predicateValue = jsonParser.readValueAs(Predicate.class);
+                    break;
+                default: throw new IOException("Cannot deserialize LogicalOperandPredicate");
+            }
+            return value;
+        }
+    }
+
+    static class Serializer extends JsonSerializer<LogicalOperandPredicate> {
+        @Override
+        public void serialize(LogicalOperandPredicate obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+            if (obj.predicateValue != null) {
+                jsonGenerator.writeObject(obj.predicateValue);
+                return;
+            }
+            if (obj.stringValue != null) {
+                jsonGenerator.writeObject(obj.stringValue);
+                return;
+            }
+            throw new IOException("LogicalOperandPredicate must not be null");
+        }
+    }
+}
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/LogicalOperandPredicateElement.java b/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/LogicalOperandPredicateElement.java
deleted file mode 100644
index e70cb12..0000000
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/LogicalOperandPredicateElement.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package io.quicktype;
-
-import java.io.IOException;
-import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.annotation.*;
-import com.fasterxml.jackson.core.type.*;
-
-/**
- * The `filter` property must be one of the predicate definitions:
- * (1) an [expression](types.html#expression) string,
- * where `datum` can be used to refer to the current data object;
- * (2) one of the field predicates: [equal predicate](filter.html#equal-predicate);
- * [range predicate](filter.html#range-predicate), [one-of
- * predicate](filter.html#one-of-predicate);
- * (3) a [selection predicate](filter.html#selection-predicate);
- * or (4) a logical operand that combines (1), (2), or (3).
- */
-@JsonDeserialize(using = LogicalOperandPredicateElement.Deserializer.class)
-@JsonSerialize(using = LogicalOperandPredicateElement.Serializer.class)
-public class LogicalOperandPredicateElement {
-    public Predicate predicateValue;
-    public String stringValue;
-
-    static class Deserializer extends JsonDeserializer<LogicalOperandPredicateElement> {
-        @Override
-        public LogicalOperandPredicateElement deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            LogicalOperandPredicateElement value = new LogicalOperandPredicateElement();
-            switch (jsonParser.currentToken()) {
-                case VALUE_STRING:
-                    String string = jsonParser.readValueAs(String.class);
-                    value.stringValue = string;
-                    break;
-                case START_OBJECT:
-                    value.predicateValue = jsonParser.readValueAs(Predicate.class);
-                    break;
-                default: throw new IOException("Cannot deserialize LogicalOperandPredicateElement");
-            }
-            return value;
-        }
-    }
-
-    static class Serializer extends JsonSerializer<LogicalOperandPredicateElement> {
-        @Override
-        public void serialize(LogicalOperandPredicateElement obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-            if (obj.predicateValue != null) {
-                jsonGenerator.writeObject(obj.predicateValue);
-                return;
-            }
-            if (obj.stringValue != null) {
-                jsonGenerator.writeObject(obj.stringValue);
-                return;
-            }
-            throw new IOException("LogicalOperandPredicateElement must not be null");
-        }
-    }
-}
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/MarkPropDefWithCondition.java b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/MarkPropDefWithCondition.java
index c5c5748..796f64b 100644
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/MarkPropDefWithCondition.java
+++ b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/MarkPropDefWithCondition.java
@@ -48,7 +48,7 @@ import java.util.List;
  */
 public class MarkPropDefWithCondition {
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private ColorCondition condition;
     private Field field;
     private Legend legend;
@@ -56,7 +56,7 @@ public class MarkPropDefWithCondition {
     private SortUnion sort;
     private TimeUnit timeUnit;
     private Type type;
-    private ConditionalPredicateValueDefValue value;
+    private ColorValue value;
 
     /**
      * Aggregation function for the field
@@ -77,9 +77,9 @@ public class MarkPropDefWithCondition {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * One or more value definition(s) with a selection predicate.
@@ -174,7 +174,7 @@ public class MarkPropDefWithCondition {
      * A constant value in visual domain.
      */
     @JsonProperty("value")
-    public ConditionalPredicateValueDefValue getValue() { return value; }
+    public ColorValue getValue() { return value; }
     @JsonProperty("value")
-    public void setValue(ConditionalPredicateValueDefValue value) { this.value = value; }
+    public void setValue(ColorValue value) { this.value = value; }
 }
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/OneOfElement.java b/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/OneOfElement.java
deleted file mode 100644
index 7e6a5e2..0000000
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/OneOfElement.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package io.quicktype;
-
-import java.io.IOException;
-import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.annotation.*;
-import com.fasterxml.jackson.core.type.*;
-
-/**
- * The value that the field should be equal to.
- */
-@JsonDeserialize(using = OneOfElement.Deserializer.class)
-@JsonSerialize(using = OneOfElement.Serializer.class)
-public class OneOfElement {
-    public Double doubleValue;
-    public Boolean boolValue;
-    public DateTime dateTimeValue;
-    public String stringValue;
-
-    static class Deserializer extends JsonDeserializer<OneOfElement> {
-        @Override
-        public OneOfElement deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            OneOfElement value = new OneOfElement();
-            switch (jsonParser.currentToken()) {
-                case VALUE_NUMBER_INT:
-                case VALUE_NUMBER_FLOAT:
-                    value.doubleValue = jsonParser.readValueAs(Double.class);
-                    break;
-                case VALUE_TRUE:
-                case VALUE_FALSE:
-                    value.boolValue = jsonParser.readValueAs(Boolean.class);
-                    break;
-                case VALUE_STRING:
-                    String string = jsonParser.readValueAs(String.class);
-                    value.stringValue = string;
-                    break;
-                case START_OBJECT:
-                    value.dateTimeValue = jsonParser.readValueAs(DateTime.class);
-                    break;
-                default: throw new IOException("Cannot deserialize OneOfElement");
-            }
-            return value;
-        }
-    }
-
-    static class Serializer extends JsonSerializer<OneOfElement> {
-        @Override
-        public void serialize(OneOfElement obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-            if (obj.doubleValue != null) {
-                jsonGenerator.writeObject(obj.doubleValue);
-                return;
-            }
-            if (obj.boolValue != null) {
-                jsonGenerator.writeObject(obj.boolValue);
-                return;
-            }
-            if (obj.dateTimeValue != null) {
-                jsonGenerator.writeObject(obj.dateTimeValue);
-                return;
-            }
-            if (obj.stringValue != null) {
-                jsonGenerator.writeObject(obj.stringValue);
-                return;
-            }
-            throw new IOException("OneOfElement must not be null");
-        }
-    }
-}
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/OrderFieldDef.java b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/OrderFieldDef.java
index de6d278..28e11ef 100644
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/OrderFieldDef.java
+++ b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/OrderFieldDef.java
@@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.*;
 
 public class OrderFieldDef {
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private Field field;
     private SortEnum sort;
     private TimeUnit timeUnit;
@@ -29,9 +29,9 @@ public class OrderFieldDef {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * __Required.__ A string defining the name of the field from which to pull a data value
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Predicate.java b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Predicate.java
index b9c3609..be0e2df 100644
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Predicate.java
+++ b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Predicate.java
@@ -4,38 +4,38 @@ import com.fasterxml.jackson.annotation.*;
 import java.util.List;
 
 public class Predicate {
-    private ConditionalValueDefLogicalOperandPredicate not;
-    private List<LogicalOperandPredicateElement> and;
-    private List<LogicalOperandPredicateElement> or;
-    private EqualUnion equal;
+    private LogicalOperandPredicate not;
+    private List<LogicalOperandPredicate> and;
+    private List<LogicalOperandPredicate> or;
+    private Equal equal;
     private String field;
     private TimeUnit timeUnit;
     private List<RangeElement> range;
-    private List<OneOfElement> oneOf;
-    private ConditionalValueDefSelectionOperand selection;
+    private List<Equal> oneOf;
+    private SelectionOperand selection;
 
     @JsonProperty("not")
-    public ConditionalValueDefLogicalOperandPredicate getNot() { return not; }
+    public LogicalOperandPredicate getNot() { return not; }
     @JsonProperty("not")
-    public void setNot(ConditionalValueDefLogicalOperandPredicate value) { this.not = value; }
+    public void setNot(LogicalOperandPredicate value) { this.not = value; }
 
     @JsonProperty("and")
-    public List<LogicalOperandPredicateElement> getAnd() { return and; }
+    public List<LogicalOperandPredicate> getAnd() { return and; }
     @JsonProperty("and")
-    public void setAnd(List<LogicalOperandPredicateElement> value) { this.and = value; }
+    public void setAnd(List<LogicalOperandPredicate> value) { this.and = value; }
 
     @JsonProperty("or")
-    public List<LogicalOperandPredicateElement> getOr() { return or; }
+    public List<LogicalOperandPredicate> getOr() { return or; }
     @JsonProperty("or")
-    public void setOr(List<LogicalOperandPredicateElement> value) { this.or = value; }
+    public void setOr(List<LogicalOperandPredicate> value) { this.or = value; }
 
     /**
      * The value that the field should be equal to.
      */
     @JsonProperty("equal")
-    public EqualUnion getEqual() { return equal; }
+    public Equal getEqual() { return equal; }
     @JsonProperty("equal")
-    public void setEqual(EqualUnion value) { this.equal = value; }
+    public void setEqual(Equal value) { this.equal = value; }
 
     /**
      * Field to be filtered.
@@ -71,15 +71,15 @@ public class Predicate {
      * for a data item included in the filtered data.
      */
     @JsonProperty("oneOf")
-    public List<OneOfElement> getOneOf() { return oneOf; }
+    public List<Equal> getOneOf() { return oneOf; }
     @JsonProperty("oneOf")
-    public void setOneOf(List<OneOfElement> value) { this.oneOf = value; }
+    public void setOneOf(List<Equal> value) { this.oneOf = value; }
 
     /**
      * Filter using a selection name.
      */
     @JsonProperty("selection")
-    public ConditionalValueDefSelectionOperand getSelection() { return selection; }
+    public SelectionOperand getSelection() { return selection; }
     @JsonProperty("selection")
-    public void setSelection(ConditionalValueDefSelectionOperand value) { this.selection = value; }
+    public void setSelection(SelectionOperand value) { this.selection = value; }
 }
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Selection.java b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Selection.java
index 16251b4..0520466 100644
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Selection.java
+++ b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Selection.java
@@ -4,22 +4,22 @@ import com.fasterxml.jackson.annotation.*;
 import java.util.List;
 
 public class Selection {
-    private ConditionalValueDefSelectionOperand not;
-    private List<SelectionOperandElement> and;
-    private List<SelectionOperandElement> or;
+    private SelectionOperand not;
+    private List<SelectionOperand> and;
+    private List<SelectionOperand> or;
 
     @JsonProperty("not")
-    public ConditionalValueDefSelectionOperand getNot() { return not; }
+    public SelectionOperand getNot() { return not; }
     @JsonProperty("not")
-    public void setNot(ConditionalValueDefSelectionOperand value) { this.not = value; }
+    public void setNot(SelectionOperand value) { this.not = value; }
 
     @JsonProperty("and")
-    public List<SelectionOperandElement> getAnd() { return and; }
+    public List<SelectionOperand> getAnd() { return and; }
     @JsonProperty("and")
-    public void setAnd(List<SelectionOperandElement> value) { this.and = value; }
+    public void setAnd(List<SelectionOperand> value) { this.and = value; }
 
     @JsonProperty("or")
-    public List<SelectionOperandElement> getOr() { return or; }
+    public List<SelectionOperand> getOr() { return or; }
     @JsonProperty("or")
-    public void setOr(List<SelectionOperandElement> value) { this.or = value; }
+    public void setOr(List<SelectionOperand> value) { this.or = value; }
 }
diff --git a/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/SelectionOperand.java b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/SelectionOperand.java
new file mode 100644
index 0000000..7aa449b
--- /dev/null
+++ b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/SelectionOperand.java
@@ -0,0 +1,54 @@
+package io.quicktype;
+
+import java.io.IOException;
+import java.io.IOException;
+import com.fasterxml.jackson.core.*;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.annotation.*;
+import com.fasterxml.jackson.core.type.*;
+
+/**
+ * Filter using a selection name.
+ *
+ * A [selection name](selection.html), or a series of [composed
+ * selections](selection.html#compose).
+ */
+@JsonDeserialize(using = SelectionOperand.Deserializer.class)
+@JsonSerialize(using = SelectionOperand.Serializer.class)
+public class SelectionOperand {
+    public Selection selectionValue;
+    public String stringValue;
+
+    static class Deserializer extends JsonDeserializer<SelectionOperand> {
+        @Override
+        public SelectionOperand deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            SelectionOperand value = new SelectionOperand();
+            switch (jsonParser.currentToken()) {
+                case VALUE_STRING:
+                    String string = jsonParser.readValueAs(String.class);
+                    value.stringValue = string;
+                    break;
+                case START_OBJECT:
+                    value.selectionValue = jsonParser.readValueAs(Selection.class);
+                    break;
+                default: throw new IOException("Cannot deserialize SelectionOperand");
+            }
+            return value;
+        }
+    }
+
+    static class Serializer extends JsonSerializer<SelectionOperand> {
+        @Override
+        public void serialize(SelectionOperand obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+            if (obj.selectionValue != null) {
+                jsonGenerator.writeObject(obj.selectionValue);
+                return;
+            }
+            if (obj.stringValue != null) {
+                jsonGenerator.writeObject(obj.stringValue);
+                return;
+            }
+            throw new IOException("SelectionOperand must not be null");
+        }
+    }
+}
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/SelectionOperandElement.java b/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/SelectionOperandElement.java
deleted file mode 100644
index 269da8d..0000000
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/SelectionOperandElement.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package io.quicktype;
-
-import java.io.IOException;
-import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.annotation.*;
-import com.fasterxml.jackson.core.type.*;
-
-/**
- * Filter using a selection name.
- *
- * A [selection name](selection.html), or a series of [composed
- * selections](selection.html#compose).
- */
-@JsonDeserialize(using = SelectionOperandElement.Deserializer.class)
-@JsonSerialize(using = SelectionOperandElement.Serializer.class)
-public class SelectionOperandElement {
-    public Selection selectionValue;
-    public String stringValue;
-
-    static class Deserializer extends JsonDeserializer<SelectionOperandElement> {
-        @Override
-        public SelectionOperandElement deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            SelectionOperandElement value = new SelectionOperandElement();
-            switch (jsonParser.currentToken()) {
-                case VALUE_STRING:
-                    String string = jsonParser.readValueAs(String.class);
-                    value.stringValue = string;
-                    break;
-                case START_OBJECT:
-                    value.selectionValue = jsonParser.readValueAs(Selection.class);
-                    break;
-                default: throw new IOException("Cannot deserialize SelectionOperandElement");
-            }
-            return value;
-        }
-    }
-
-    static class Serializer extends JsonSerializer<SelectionOperandElement> {
-        @Override
-        public void serialize(SelectionOperandElement obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-            if (obj.selectionValue != null) {
-                jsonGenerator.writeObject(obj.selectionValue);
-                return;
-            }
-            if (obj.stringValue != null) {
-                jsonGenerator.writeObject(obj.stringValue);
-                return;
-            }
-            throw new IOException("SelectionOperandElement must not be null");
-        }
-    }
-}
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/TextDefWithCondition.java b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/TextDefWithCondition.java
index bab354b..5bc625d 100644
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/TextDefWithCondition.java
+++ b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/TextDefWithCondition.java
@@ -23,13 +23,13 @@ import java.util.List;
  */
 public class TextDefWithCondition {
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private TextCondition condition;
     private Field field;
     private String format;
     private TimeUnit timeUnit;
     private Type type;
-    private ConditionalPredicateValueDefValue value;
+    private ColorValue value;
 
     /**
      * Aggregation function for the field
@@ -50,9 +50,9 @@ public class TextDefWithCondition {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * One or more value definition(s) with a selection predicate.
@@ -120,7 +120,7 @@ public class TextDefWithCondition {
      * A constant value in visual domain.
      */
     @JsonProperty("value")
-    public ConditionalPredicateValueDefValue getValue() { return value; }
+    public ColorValue getValue() { return value; }
     @JsonProperty("value")
-    public void setValue(ConditionalPredicateValueDefValue value) { this.value = value; }
+    public void setValue(ColorValue value) { this.value = value; }
 }
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Transform.java b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Transform.java
index cbf0ea3..1065f00 100644
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Transform.java
+++ b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Transform.java
@@ -4,13 +4,13 @@ import com.fasterxml.jackson.annotation.*;
 import java.util.List;
 
 public class Transform {
-    private ConditionalValueDefLogicalOperandPredicate filter;
+    private LogicalOperandPredicate filter;
     private Style as;
     private String calculate;
     private String transformDefault;
     private LookupData from;
     private String lookup;
-    private Bin bin;
+    private TransformBin bin;
     private String field;
     private TimeUnit timeUnit;
     private List<AggregatedFieldDef> aggregate;
@@ -27,9 +27,9 @@ public class Transform {
      * or (4) a logical operand that combines (1), (2), or (3).
      */
     @JsonProperty("filter")
-    public ConditionalValueDefLogicalOperandPredicate getFilter() { return filter; }
+    public LogicalOperandPredicate getFilter() { return filter; }
     @JsonProperty("filter")
-    public void setFilter(ConditionalValueDefLogicalOperandPredicate value) { this.filter = value; }
+    public void setFilter(LogicalOperandPredicate value) { this.filter = value; }
 
     /**
      * The field for storing the computed formula value.
@@ -87,9 +87,9 @@ public class Transform {
      * An object indicating bin properties, or simply `true` for using default bin parameters.
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public TransformBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(TransformBin value) { this.bin = value; }
 
     /**
      * The data field to bin.
diff --git a/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/TransformBin.java b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/TransformBin.java
new file mode 100644
index 0000000..ae29fc2
--- /dev/null
+++ b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/TransformBin.java
@@ -0,0 +1,48 @@
+package io.quicktype;
+
+import java.io.IOException;
+import java.io.IOException;
+import com.fasterxml.jackson.core.*;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.annotation.*;
+import com.fasterxml.jackson.core.type.*;
+
+@JsonDeserialize(using = TransformBin.Deserializer.class)
+@JsonSerialize(using = TransformBin.Serializer.class)
+public class TransformBin {
+    public Boolean boolValue;
+    public BinParams binParamsValue;
+
+    static class Deserializer extends JsonDeserializer<TransformBin> {
+        @Override
+        public TransformBin deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            TransformBin value = new TransformBin();
+            switch (jsonParser.currentToken()) {
+                case VALUE_TRUE:
+                case VALUE_FALSE:
+                    value.boolValue = jsonParser.readValueAs(Boolean.class);
+                    break;
+                case START_OBJECT:
+                    value.binParamsValue = jsonParser.readValueAs(BinParams.class);
+                    break;
+                default: throw new IOException("Cannot deserialize TransformBin");
+            }
+            return value;
+        }
+    }
+
+    static class Serializer extends JsonSerializer<TransformBin> {
+        @Override
+        public void serialize(TransformBin obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+            if (obj.boolValue != null) {
+                jsonGenerator.writeObject(obj.boolValue);
+                return;
+            }
+            if (obj.binParamsValue != null) {
+                jsonGenerator.writeObject(obj.binParamsValue);
+                return;
+            }
+            throw new IOException("TransformBin must not be null");
+        }
+    }
+}
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Values.java b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Values.java
index dc130c0..486b136 100644
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Values.java
+++ b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Values.java
@@ -27,8 +27,6 @@ public class Values {
         public Values deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
             Values value = new Values();
             switch (jsonParser.currentToken()) {
-                case VALUE_NULL:
-                    break;
                 case VALUE_STRING:
                     String string = jsonParser.readValueAs(String.class);
                     value.stringValue = string;
@@ -60,7 +58,7 @@ public class Values {
                 jsonGenerator.writeObject(obj.stringValue);
                 return;
             }
-            jsonGenerator.writeNull();
+            throw new IOException("Values must not be null");
         }
     }
 }
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/X2Class.java b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/X2Class.java
index 4742838..38d62b5 100644
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/X2Class.java
+++ b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/X2Class.java
@@ -13,11 +13,11 @@ import com.fasterxml.jackson.annotation.*;
  */
 public class X2Class {
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private Field field;
     private TimeUnit timeUnit;
     private Type type;
-    private ConditionalPredicateValueDefValue value;
+    private ConditionalValueDefValue value;
 
     /**
      * Aggregation function for the field
@@ -38,9 +38,9 @@ public class X2Class {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * __Required.__ A string defining the name of the field from which to pull a data value
@@ -86,7 +86,7 @@ public class X2Class {
      * `0` to `1` for opacity).
      */
     @JsonProperty("value")
-    public ConditionalPredicateValueDefValue getValue() { return value; }
+    public ConditionalValueDefValue getValue() { return value; }
     @JsonProperty("value")
-    public void setValue(ConditionalPredicateValueDefValue value) { this.value = value; }
+    public void setValue(ConditionalValueDefValue value) { this.value = value; }
 }
diff --git a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/XClass.java b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/XClass.java
index 38c4a64..c71f712 100644
--- a/base/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/XClass.java
+++ b/head/schema-java/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/XClass.java
@@ -12,14 +12,14 @@ import com.fasterxml.jackson.annotation.*;
 public class XClass {
     private AggregateOp aggregate;
     private Axis axis;
-    private Bin bin;
+    private ColorBin bin;
     private Field field;
     private Scale scale;
     private SortUnion sort;
     private StackOffset stack;
     private TimeUnit timeUnit;
     private Type type;
-    private ConditionalPredicateValueDefValue value;
+    private ConditionalValueDefValue value;
 
     /**
      * Aggregation function for the field
@@ -51,9 +51,9 @@ public class XClass {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * __Required.__ A string defining the name of the field from which to pull a data value
@@ -151,7 +151,7 @@ public class XClass {
      * `0` to `1` for opacity).
      */
     @JsonProperty("value")
-    public ConditionalPredicateValueDefValue getValue() { return value; }
+    public ConditionalValueDefValue getValue() { return value; }
     @JsonProperty("value")
-    public void setValue(ConditionalPredicateValueDefValue value) { this.value = value; }
+    public void setValue(ConditionalValueDefValue value) { this.value = value; }
 }
diff --git a/head/schema-java-datetime-legacy/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/Anyof.java b/head/schema-java-datetime-legacy/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/Anyof.java
new file mode 100644
index 0000000..500bdc2
--- /dev/null
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/Anyof.java
@@ -0,0 +1,18 @@
+package io.quicktype;
+
+import com.fasterxml.jackson.annotation.*;
+
+public class Anyof {
+    private String name;
+    private String size;
+
+    @JsonProperty("name")
+    public String getName() { return name; }
+    @JsonProperty("name")
+    public void setName(String value) { this.name = value; }
+
+    @JsonProperty("size")
+    public String getSize() { return size; }
+    @JsonProperty("size")
+    public void setSize(String value) { this.size = value; }
+}
diff --git a/head/schema-java-datetime-legacy/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/Converter.java b/head/schema-java-datetime-legacy/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/Converter.java
new file mode 100644
index 0000000..7d4811b
--- /dev/null
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/Converter.java
@@ -0,0 +1,121 @@
+// To use this code, add the following Maven dependency to your project:
+//
+//
+//     com.fasterxml.jackson.core     : jackson-databind          : 2.9.0
+//
+//
+// Import this package:
+//
+//     import io.quicktype.Converter;
+//
+// Then you can deserialize a JSON string with
+//
+//     TopLevel data = Converter.fromJsonString(jsonString);
+
+package io.quicktype;
+
+import java.io.IOException;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import java.util.*;
+import java.util.Date;
+import java.text.SimpleDateFormat;
+
+public class Converter {
+    // Date-time helpers
+
+    private static final String[] DATE_TIME_FORMATS = {
+            "yyyy-MM-dd'T'HH:mm:ss.SX",
+            "yyyy-MM-dd'T'HH:mm:ss.S",
+            "yyyy-MM-dd'T'HH:mm:ssX",
+            "yyyy-MM-dd'T'HH:mm:ss",
+            "yyyy-MM-dd HH:mm:ss.SX",
+            "yyyy-MM-dd HH:mm:ss.S",
+            "yyyy-MM-dd HH:mm:ssX",
+            "yyyy-MM-dd HH:mm:ss",
+            "HH:mm:ss.SZ",
+            "HH:mm:ss.S",
+            "HH:mm:ssZ",
+            "HH:mm:ss",
+            "yyyy-MM-dd",
+    };
+
+    public static Date parseAllDateTimeString(String str) {
+        for (String format : DATE_TIME_FORMATS) {
+            try {
+                return new SimpleDateFormat(format).parse(str);
+            } catch (Exception ex) {
+                // Ignored
+            }
+        }
+        return null;
+    }
+
+    public static String serializeDateTime(Date datetime) {
+        return new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssZ").format(datetime);
+    }
+
+    public static String serializeDate(Date datetime) {
+        return new SimpleDateFormat("yyyy-MM-dd").format(datetime);
+    }
+
+    public static String serializeTime(Date datetime) {
+        return new SimpleDateFormat("hh:mm:ssZ").format(datetime);
+    }
+    // Serialize/deserialize helpers
+
+    public static TopLevel fromJsonString(String json) throws IOException {
+        return getObjectReader().readValue(json);
+    }
+
+    public static String toJsonString(TopLevel obj) throws JsonProcessingException {
+        return getObjectWriter().writeValueAsString(obj);
+    }
+
+    private static ObjectReader reader;
+    private static ObjectWriter writer;
+
+    private static void instantiateMapper() {
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.findAndRegisterModules();
+        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
+        SimpleModule module = new SimpleModule();
+        module.addDeserializer(Date.class, new JsonDeserializer<Date>() {
+            @Override
+            public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+                String value = jsonParser.getText();
+                return Converter.parseAllDateTimeString(value);
+            }
+        });
+        module.addDeserializer(Date.class, new JsonDeserializer<Date>() {
+            @Override
+            public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+                String value = jsonParser.getText();
+                return Converter.parseAllDateTimeString(value);
+            }
+        });
+        module.addDeserializer(Date.class, new JsonDeserializer<Date>() {
+            @Override
+            public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+                String value = jsonParser.getText();
+                return Converter.parseAllDateTimeString(value);
+            }
+        });
+        mapper.registerModule(module);
+        reader = mapper.readerFor(TopLevel.class);
+        writer = mapper.writerFor(TopLevel.class);
+    }
+
+    private static ObjectReader getObjectReader() {
+        if (reader == null) instantiateMapper();
+        return reader;
+    }
+
+    private static ObjectWriter getObjectWriter() {
+        if (writer == null) instantiateMapper();
+        return writer;
+    }
+}
diff --git a/head/schema-java-datetime-legacy/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/TopLevel.java b/head/schema-java-datetime-legacy/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/TopLevel.java
new file mode 100644
index 0000000..b180d63
--- /dev/null
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/TopLevel.java
@@ -0,0 +1,12 @@
+package io.quicktype;
+
+import com.fasterxml.jackson.annotation.*;
+
+public class TopLevel {
+    private Anyof anyof;
+
+    @JsonProperty("anyof")
+    public Anyof getAnyof() { return anyof; }
+    @JsonProperty("anyof")
+    public void setAnyof(Anyof value) { this.anyof = value; }
+}
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/AnyMark.java b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/AnyMark.java
index 7ffb7ef..ff16a90 100644
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/AnyMark.java
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/AnyMark.java
@@ -24,8 +24,6 @@ public class AnyMark {
         public AnyMark deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
             AnyMark value = new AnyMark();
             switch (jsonParser.currentToken()) {
-                case VALUE_NULL:
-                    break;
                 case VALUE_STRING:
                     String string = jsonParser.readValueAs(String.class);
                     try {
@@ -54,7 +52,7 @@ public class AnyMark {
                 jsonGenerator.writeObject(obj.enumValue);
                 return;
             }
-            jsonGenerator.writeNull();
+            throw new IOException("AnyMark must not be null");
         }
     }
 }
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Bin.java b/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Bin.java
deleted file mode 100644
index f2b4b13..0000000
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Bin.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package io.quicktype;
-
-import java.io.IOException;
-import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.annotation.*;
-import com.fasterxml.jackson.core.type.*;
-
-@JsonDeserialize(using = Bin.Deserializer.class)
-@JsonSerialize(using = Bin.Serializer.class)
-public class Bin {
-    public Boolean boolValue;
-    public BinParams binParamsValue;
-
-    static class Deserializer extends JsonDeserializer<Bin> {
-        @Override
-        public Bin deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            Bin value = new Bin();
-            switch (jsonParser.currentToken()) {
-                case VALUE_NULL:
-                    break;
-                case VALUE_TRUE:
-                case VALUE_FALSE:
-                    value.boolValue = jsonParser.readValueAs(Boolean.class);
-                    break;
-                case START_OBJECT:
-                    value.binParamsValue = jsonParser.readValueAs(BinParams.class);
-                    break;
-                default: throw new IOException("Cannot deserialize Bin");
-            }
-            return value;
-        }
-    }
-
-    static class Serializer extends JsonSerializer<Bin> {
-        @Override
-        public void serialize(Bin obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-            if (obj.boolValue != null) {
-                jsonGenerator.writeObject(obj.boolValue);
-                return;
-            }
-            if (obj.binParamsValue != null) {
-                jsonGenerator.writeObject(obj.binParamsValue);
-                return;
-            }
-            jsonGenerator.writeNull();
-        }
-    }
-}
diff --git a/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ColorBin.java b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ColorBin.java
new file mode 100644
index 0000000..ba25f2a
--- /dev/null
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ColorBin.java
@@ -0,0 +1,50 @@
+package io.quicktype;
+
+import java.io.IOException;
+import java.io.IOException;
+import com.fasterxml.jackson.core.*;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.annotation.*;
+import com.fasterxml.jackson.core.type.*;
+
+@JsonDeserialize(using = ColorBin.Deserializer.class)
+@JsonSerialize(using = ColorBin.Serializer.class)
+public class ColorBin {
+    public Boolean boolValue;
+    public BinParams binParamsValue;
+
+    static class Deserializer extends JsonDeserializer<ColorBin> {
+        @Override
+        public ColorBin deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            ColorBin value = new ColorBin();
+            switch (jsonParser.currentToken()) {
+                case VALUE_NULL:
+                    break;
+                case VALUE_TRUE:
+                case VALUE_FALSE:
+                    value.boolValue = jsonParser.readValueAs(Boolean.class);
+                    break;
+                case START_OBJECT:
+                    value.binParamsValue = jsonParser.readValueAs(BinParams.class);
+                    break;
+                default: throw new IOException("Cannot deserialize ColorBin");
+            }
+            return value;
+        }
+    }
+
+    static class Serializer extends JsonSerializer<ColorBin> {
+        @Override
+        public void serialize(ColorBin obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+            if (obj.boolValue != null) {
+                jsonGenerator.writeObject(obj.boolValue);
+                return;
+            }
+            if (obj.binParamsValue != null) {
+                jsonGenerator.writeObject(obj.binParamsValue);
+                return;
+            }
+            jsonGenerator.writeNull();
+        }
+    }
+}
diff --git a/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ColorValue.java b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ColorValue.java
new file mode 100644
index 0000000..bb6fb5b
--- /dev/null
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ColorValue.java
@@ -0,0 +1,66 @@
+package io.quicktype;
+
+import java.io.IOException;
+import java.io.IOException;
+import com.fasterxml.jackson.core.*;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.annotation.*;
+import com.fasterxml.jackson.core.type.*;
+
+/**
+ * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
+ * `0` to `1` for opacity).
+ *
+ * A constant value in visual domain.
+ */
+@JsonDeserialize(using = ColorValue.Deserializer.class)
+@JsonSerialize(using = ColorValue.Serializer.class)
+public class ColorValue {
+    public Double doubleValue;
+    public Boolean boolValue;
+    public String stringValue;
+
+    static class Deserializer extends JsonDeserializer<ColorValue> {
+        @Override
+        public ColorValue deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            ColorValue value = new ColorValue();
+            switch (jsonParser.currentToken()) {
+                case VALUE_NULL:
+                    break;
+                case VALUE_NUMBER_INT:
+                case VALUE_NUMBER_FLOAT:
+                    value.doubleValue = jsonParser.readValueAs(Double.class);
+                    break;
+                case VALUE_TRUE:
+                case VALUE_FALSE:
+                    value.boolValue = jsonParser.readValueAs(Boolean.class);
+                    break;
+                case VALUE_STRING:
+                    String string = jsonParser.readValueAs(String.class);
+                    value.stringValue = string;
+                    break;
+                default: throw new IOException("Cannot deserialize ColorValue");
+            }
+            return value;
+        }
+    }
+
+    static class Serializer extends JsonSerializer<ColorValue> {
+        @Override
+        public void serialize(ColorValue obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+            if (obj.doubleValue != null) {
+                jsonGenerator.writeObject(obj.doubleValue);
+                return;
+            }
+            if (obj.boolValue != null) {
+                jsonGenerator.writeObject(obj.boolValue);
+                return;
+            }
+            if (obj.stringValue != null) {
+                jsonGenerator.writeObject(obj.stringValue);
+                return;
+            }
+            jsonGenerator.writeNull();
+        }
+    }
+}
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateFieldDefClass.java b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateFieldDefClass.java
index 0ee72f6..d883001 100644
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateFieldDefClass.java
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateFieldDefClass.java
@@ -3,37 +3,37 @@ package io.quicktype;
 import com.fasterxml.jackson.annotation.*;
 
 public class ConditionalPredicateFieldDefClass {
-    private ConditionalValueDefLogicalOperandPredicate test;
-    private ConditionalPredicateValueDefValue value;
-    private ConditionalValueDefSelectionOperand selection;
+    private LogicalOperandPredicate test;
+    private ConditionalValueDefValue value;
+    private SelectionOperand selection;
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private Field field;
     private TimeUnit timeUnit;
     private Type type;
 
     @JsonProperty("test")
-    public ConditionalValueDefLogicalOperandPredicate getTest() { return test; }
+    public LogicalOperandPredicate getTest() { return test; }
     @JsonProperty("test")
-    public void setTest(ConditionalValueDefLogicalOperandPredicate value) { this.test = value; }
+    public void setTest(LogicalOperandPredicate value) { this.test = value; }
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
     @JsonProperty("value")
-    public ConditionalPredicateValueDefValue getValue() { return value; }
+    public ConditionalValueDefValue getValue() { return value; }
     @JsonProperty("value")
-    public void setValue(ConditionalPredicateValueDefValue value) { this.value = value; }
+    public void setValue(ConditionalValueDefValue value) { this.value = value; }
 
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
     @JsonProperty("selection")
-    public ConditionalValueDefSelectionOperand getSelection() { return selection; }
+    public SelectionOperand getSelection() { return selection; }
     @JsonProperty("selection")
-    public void setSelection(ConditionalValueDefSelectionOperand value) { this.selection = value; }
+    public void setSelection(SelectionOperand value) { this.selection = value; }
 
     /**
      * Aggregation function for the field
@@ -54,9 +54,9 @@ public class ConditionalPredicateFieldDefClass {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * __Required.__ A string defining the name of the field from which to pull a data value
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateMarkPropFieldDefClass.java b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateMarkPropFieldDefClass.java
index bd46210..cf72cce 100644
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateMarkPropFieldDefClass.java
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateMarkPropFieldDefClass.java
@@ -3,11 +3,11 @@ package io.quicktype;
 import com.fasterxml.jackson.annotation.*;
 
 public class ConditionalPredicateMarkPropFieldDefClass {
-    private ConditionalValueDefLogicalOperandPredicate test;
-    private ConditionalPredicateValueDefValue value;
-    private ConditionalValueDefSelectionOperand selection;
+    private LogicalOperandPredicate test;
+    private ConditionalValueDefValue value;
+    private SelectionOperand selection;
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private Field field;
     private Legend legend;
     private Scale scale;
@@ -16,27 +16,27 @@ public class ConditionalPredicateMarkPropFieldDefClass {
     private Type type;
 
     @JsonProperty("test")
-    public ConditionalValueDefLogicalOperandPredicate getTest() { return test; }
+    public LogicalOperandPredicate getTest() { return test; }
     @JsonProperty("test")
-    public void setTest(ConditionalValueDefLogicalOperandPredicate value) { this.test = value; }
+    public void setTest(LogicalOperandPredicate value) { this.test = value; }
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
     @JsonProperty("value")
-    public ConditionalPredicateValueDefValue getValue() { return value; }
+    public ConditionalValueDefValue getValue() { return value; }
     @JsonProperty("value")
-    public void setValue(ConditionalPredicateValueDefValue value) { this.value = value; }
+    public void setValue(ConditionalValueDefValue value) { this.value = value; }
 
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
     @JsonProperty("selection")
-    public ConditionalValueDefSelectionOperand getSelection() { return selection; }
+    public SelectionOperand getSelection() { return selection; }
     @JsonProperty("selection")
-    public void setSelection(ConditionalValueDefSelectionOperand value) { this.selection = value; }
+    public void setSelection(SelectionOperand value) { this.selection = value; }
 
     /**
      * Aggregation function for the field
@@ -57,9 +57,9 @@ public class ConditionalPredicateMarkPropFieldDefClass {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * __Required.__ A string defining the name of the field from which to pull a data value
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateTextFieldDefClass.java b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateTextFieldDefClass.java
index eafdc1a..8141189 100644
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateTextFieldDefClass.java
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateTextFieldDefClass.java
@@ -3,38 +3,38 @@ package io.quicktype;
 import com.fasterxml.jackson.annotation.*;
 
 public class ConditionalPredicateTextFieldDefClass {
-    private ConditionalValueDefLogicalOperandPredicate test;
-    private ConditionalPredicateValueDefValue value;
-    private ConditionalValueDefSelectionOperand selection;
+    private LogicalOperandPredicate test;
+    private ConditionalValueDefValue value;
+    private SelectionOperand selection;
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private Field field;
     private String format;
     private TimeUnit timeUnit;
     private Type type;
 
     @JsonProperty("test")
-    public ConditionalValueDefLogicalOperandPredicate getTest() { return test; }
+    public LogicalOperandPredicate getTest() { return test; }
     @JsonProperty("test")
-    public void setTest(ConditionalValueDefLogicalOperandPredicate value) { this.test = value; }
+    public void setTest(LogicalOperandPredicate value) { this.test = value; }
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
     @JsonProperty("value")
-    public ConditionalPredicateValueDefValue getValue() { return value; }
+    public ConditionalValueDefValue getValue() { return value; }
     @JsonProperty("value")
-    public void setValue(ConditionalPredicateValueDefValue value) { this.value = value; }
+    public void setValue(ConditionalValueDefValue value) { this.value = value; }
 
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
     @JsonProperty("selection")
-    public ConditionalValueDefSelectionOperand getSelection() { return selection; }
+    public SelectionOperand getSelection() { return selection; }
     @JsonProperty("selection")
-    public void setSelection(ConditionalValueDefSelectionOperand value) { this.selection = value; }
+    public void setSelection(SelectionOperand value) { this.selection = value; }
 
     /**
      * Aggregation function for the field
@@ -55,9 +55,9 @@ public class ConditionalPredicateTextFieldDefClass {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * __Required.__ A string defining the name of the field from which to pull a data value
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateValueDefValue.java b/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateValueDefValue.java
deleted file mode 100644
index fe41fbe..0000000
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateValueDefValue.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package io.quicktype;
-
-import java.io.IOException;
-import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.annotation.*;
-import com.fasterxml.jackson.core.type.*;
-
-/**
- * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
- * `0` to `1` for opacity).
- *
- * A constant value in visual domain.
- */
-@JsonDeserialize(using = ConditionalPredicateValueDefValue.Deserializer.class)
-@JsonSerialize(using = ConditionalPredicateValueDefValue.Serializer.class)
-public class ConditionalPredicateValueDefValue {
-    public Double doubleValue;
-    public Boolean boolValue;
-    public String stringValue;
-
-    static class Deserializer extends JsonDeserializer<ConditionalPredicateValueDefValue> {
-        @Override
-        public ConditionalPredicateValueDefValue deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            ConditionalPredicateValueDefValue value = new ConditionalPredicateValueDefValue();
-            switch (jsonParser.currentToken()) {
-                case VALUE_NULL:
-                    break;
-                case VALUE_NUMBER_INT:
-                case VALUE_NUMBER_FLOAT:
-                    value.doubleValue = jsonParser.readValueAs(Double.class);
-                    break;
-                case VALUE_TRUE:
-                case VALUE_FALSE:
-                    value.boolValue = jsonParser.readValueAs(Boolean.class);
-                    break;
-                case VALUE_STRING:
-                    String string = jsonParser.readValueAs(String.class);
-                    value.stringValue = string;
-                    break;
-                default: throw new IOException("Cannot deserialize ConditionalPredicateValueDefValue");
-            }
-            return value;
-        }
-    }
-
-    static class Serializer extends JsonSerializer<ConditionalPredicateValueDefValue> {
-        @Override
-        public void serialize(ConditionalPredicateValueDefValue obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-            if (obj.doubleValue != null) {
-                jsonGenerator.writeObject(obj.doubleValue);
-                return;
-            }
-            if (obj.boolValue != null) {
-                jsonGenerator.writeObject(obj.boolValue);
-                return;
-            }
-            if (obj.stringValue != null) {
-                jsonGenerator.writeObject(obj.stringValue);
-                return;
-            }
-            jsonGenerator.writeNull();
-        }
-    }
-}
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDef.java b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDef.java
index d11e6b0..4853170 100644
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDef.java
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDef.java
@@ -3,14 +3,14 @@ package io.quicktype;
 import com.fasterxml.jackson.annotation.*;
 
 public class ConditionalValueDef {
-    private ConditionalValueDefLogicalOperandPredicate test;
+    private LogicalOperandPredicate test;
     private ConditionalValueDefValue value;
-    private ConditionalValueDefSelectionOperand selection;
+    private SelectionOperand selection;
 
     @JsonProperty("test")
-    public ConditionalValueDefLogicalOperandPredicate getTest() { return test; }
+    public LogicalOperandPredicate getTest() { return test; }
     @JsonProperty("test")
-    public void setTest(ConditionalValueDefLogicalOperandPredicate value) { this.test = value; }
+    public void setTest(LogicalOperandPredicate value) { this.test = value; }
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
@@ -26,7 +26,7 @@ public class ConditionalValueDef {
      * selections](selection.html#compose).
      */
     @JsonProperty("selection")
-    public ConditionalValueDefSelectionOperand getSelection() { return selection; }
+    public SelectionOperand getSelection() { return selection; }
     @JsonProperty("selection")
-    public void setSelection(ConditionalValueDefSelectionOperand value) { this.selection = value; }
+    public void setSelection(SelectionOperand value) { this.selection = value; }
 }
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDefLogicalOperandPredicate.java b/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDefLogicalOperandPredicate.java
deleted file mode 100644
index f4bf576..0000000
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDefLogicalOperandPredicate.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package io.quicktype;
-
-import java.io.IOException;
-import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.annotation.*;
-import com.fasterxml.jackson.core.type.*;
-
-/**
- * The `filter` property must be one of the predicate definitions:
- * (1) an [expression](types.html#expression) string,
- * where `datum` can be used to refer to the current data object;
- * (2) one of the field predicates: [equal predicate](filter.html#equal-predicate);
- * [range predicate](filter.html#range-predicate), [one-of
- * predicate](filter.html#one-of-predicate);
- * (3) a [selection predicate](filter.html#selection-predicate);
- * or (4) a logical operand that combines (1), (2), or (3).
- */
-@JsonDeserialize(using = ConditionalValueDefLogicalOperandPredicate.Deserializer.class)
-@JsonSerialize(using = ConditionalValueDefLogicalOperandPredicate.Serializer.class)
-public class ConditionalValueDefLogicalOperandPredicate {
-    public Predicate predicateValue;
-    public String stringValue;
-
-    static class Deserializer extends JsonDeserializer<ConditionalValueDefLogicalOperandPredicate> {
-        @Override
-        public ConditionalValueDefLogicalOperandPredicate deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            ConditionalValueDefLogicalOperandPredicate value = new ConditionalValueDefLogicalOperandPredicate();
-            switch (jsonParser.currentToken()) {
-                case VALUE_NULL:
-                    break;
-                case VALUE_STRING:
-                    String string = jsonParser.readValueAs(String.class);
-                    value.stringValue = string;
-                    break;
-                case START_OBJECT:
-                    value.predicateValue = jsonParser.readValueAs(Predicate.class);
-                    break;
-                default: throw new IOException("Cannot deserialize ConditionalValueDefLogicalOperandPredicate");
-            }
-            return value;
-        }
-    }
-
-    static class Serializer extends JsonSerializer<ConditionalValueDefLogicalOperandPredicate> {
-        @Override
-        public void serialize(ConditionalValueDefLogicalOperandPredicate obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-            if (obj.predicateValue != null) {
-                jsonGenerator.writeObject(obj.predicateValue);
-                return;
-            }
-            if (obj.stringValue != null) {
-                jsonGenerator.writeObject(obj.stringValue);
-                return;
-            }
-            jsonGenerator.writeNull();
-        }
-    }
-}
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDefSelectionOperand.java b/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDefSelectionOperand.java
deleted file mode 100644
index 3ee477d..0000000
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDefSelectionOperand.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package io.quicktype;
-
-import java.io.IOException;
-import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.annotation.*;
-import com.fasterxml.jackson.core.type.*;
-
-/**
- * Filter using a selection name.
- *
- * A [selection name](selection.html), or a series of [composed
- * selections](selection.html#compose).
- */
-@JsonDeserialize(using = ConditionalValueDefSelectionOperand.Deserializer.class)
-@JsonSerialize(using = ConditionalValueDefSelectionOperand.Serializer.class)
-public class ConditionalValueDefSelectionOperand {
-    public Selection selectionValue;
-    public String stringValue;
-
-    static class Deserializer extends JsonDeserializer<ConditionalValueDefSelectionOperand> {
-        @Override
-        public ConditionalValueDefSelectionOperand deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            ConditionalValueDefSelectionOperand value = new ConditionalValueDefSelectionOperand();
-            switch (jsonParser.currentToken()) {
-                case VALUE_NULL:
-                    break;
-                case VALUE_STRING:
-                    String string = jsonParser.readValueAs(String.class);
-                    value.stringValue = string;
-                    break;
-                case START_OBJECT:
-                    value.selectionValue = jsonParser.readValueAs(Selection.class);
-                    break;
-                default: throw new IOException("Cannot deserialize ConditionalValueDefSelectionOperand");
-            }
-            return value;
-        }
-    }
-
-    static class Serializer extends JsonSerializer<ConditionalValueDefSelectionOperand> {
-        @Override
-        public void serialize(ConditionalValueDefSelectionOperand obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-            if (obj.selectionValue != null) {
-                jsonGenerator.writeObject(obj.selectionValue);
-                return;
-            }
-            if (obj.stringValue != null) {
-                jsonGenerator.writeObject(obj.stringValue);
-                return;
-            }
-            jsonGenerator.writeNull();
-        }
-    }
-}
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/DefWithCondition.java b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/DefWithCondition.java
index d044c42..19c0bbb 100644
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/DefWithCondition.java
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/DefWithCondition.java
@@ -21,12 +21,12 @@ import java.util.List;
  */
 public class DefWithCondition {
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private HrefCondition condition;
     private Field field;
     private TimeUnit timeUnit;
     private Type type;
-    private ConditionalPredicateValueDefValue value;
+    private ColorValue value;
 
     /**
      * Aggregation function for the field
@@ -47,9 +47,9 @@ public class DefWithCondition {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * One or more value definition(s) with a selection predicate.
@@ -108,7 +108,7 @@ public class DefWithCondition {
      * A constant value in visual domain.
      */
     @JsonProperty("value")
-    public ConditionalPredicateValueDefValue getValue() { return value; }
+    public ColorValue getValue() { return value; }
     @JsonProperty("value")
-    public void setValue(ConditionalPredicateValueDefValue value) { this.value = value; }
+    public void setValue(ColorValue value) { this.value = value; }
 }
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/DomainUnion.java b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/DomainUnion.java
index e70f578..0f19e22 100644
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/DomainUnion.java
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/DomainUnion.java
@@ -29,7 +29,7 @@ import java.util.List;
 @JsonDeserialize(using = DomainUnion.Deserializer.class)
 @JsonSerialize(using = DomainUnion.Serializer.class)
 public class DomainUnion {
-    public List<OneOfElement> unionArrayValue;
+    public List<Equal> unionArrayValue;
     public DomainClass domainClassValue;
     public Domain enumValue;
 
@@ -49,7 +49,7 @@ public class DomainUnion {
                     }
                     break;
                 case START_ARRAY:
-                    value.unionArrayValue = jsonParser.readValueAs(new TypeReference<List<OneOfElement>>() {});
+                    value.unionArrayValue = jsonParser.readValueAs(new TypeReference<List<Equal>>() {});
                     break;
                 case START_OBJECT:
                     value.domainClassValue = jsonParser.readValueAs(DomainClass.class);
diff --git a/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Equal.java b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Equal.java
new file mode 100644
index 0000000..9254aa8
--- /dev/null
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Equal.java
@@ -0,0 +1,69 @@
+package io.quicktype;
+
+import java.io.IOException;
+import java.io.IOException;
+import com.fasterxml.jackson.core.*;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.annotation.*;
+import com.fasterxml.jackson.core.type.*;
+
+/**
+ * The value that the field should be equal to.
+ */
+@JsonDeserialize(using = Equal.Deserializer.class)
+@JsonSerialize(using = Equal.Serializer.class)
+public class Equal {
+    public Double doubleValue;
+    public Boolean boolValue;
+    public DateTime dateTimeValue;
+    public String stringValue;
+
+    static class Deserializer extends JsonDeserializer<Equal> {
+        @Override
+        public Equal deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            Equal value = new Equal();
+            switch (jsonParser.currentToken()) {
+                case VALUE_NUMBER_INT:
+                case VALUE_NUMBER_FLOAT:
+                    value.doubleValue = jsonParser.readValueAs(Double.class);
+                    break;
+                case VALUE_TRUE:
+                case VALUE_FALSE:
+                    value.boolValue = jsonParser.readValueAs(Boolean.class);
+                    break;
+                case VALUE_STRING:
+                    String string = jsonParser.readValueAs(String.class);
+                    value.stringValue = string;
+                    break;
+                case START_OBJECT:
+                    value.dateTimeValue = jsonParser.readValueAs(DateTime.class);
+                    break;
+                default: throw new IOException("Cannot deserialize Equal");
+            }
+            return value;
+        }
+    }
+
+    static class Serializer extends JsonSerializer<Equal> {
+        @Override
+        public void serialize(Equal obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+            if (obj.doubleValue != null) {
+                jsonGenerator.writeObject(obj.doubleValue);
+                return;
+            }
+            if (obj.boolValue != null) {
+                jsonGenerator.writeObject(obj.boolValue);
+                return;
+            }
+            if (obj.dateTimeValue != null) {
+                jsonGenerator.writeObject(obj.dateTimeValue);
+                return;
+            }
+            if (obj.stringValue != null) {
+                jsonGenerator.writeObject(obj.stringValue);
+                return;
+            }
+            throw new IOException("Equal must not be null");
+        }
+    }
+}
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/EqualUnion.java b/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/EqualUnion.java
deleted file mode 100644
index cde8d77..0000000
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/EqualUnion.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package io.quicktype;
-
-import java.io.IOException;
-import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.annotation.*;
-import com.fasterxml.jackson.core.type.*;
-
-/**
- * The value that the field should be equal to.
- */
-@JsonDeserialize(using = EqualUnion.Deserializer.class)
-@JsonSerialize(using = EqualUnion.Serializer.class)
-public class EqualUnion {
-    public Double doubleValue;
-    public Boolean boolValue;
-    public DateTime dateTimeValue;
-    public String stringValue;
-
-    static class Deserializer extends JsonDeserializer<EqualUnion> {
-        @Override
-        public EqualUnion deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            EqualUnion value = new EqualUnion();
-            switch (jsonParser.currentToken()) {
-                case VALUE_NULL:
-                    break;
-                case VALUE_NUMBER_INT:
-                case VALUE_NUMBER_FLOAT:
-                    value.doubleValue = jsonParser.readValueAs(Double.class);
-                    break;
-                case VALUE_TRUE:
-                case VALUE_FALSE:
-                    value.boolValue = jsonParser.readValueAs(Boolean.class);
-                    break;
-                case VALUE_STRING:
-                    String string = jsonParser.readValueAs(String.class);
-                    value.stringValue = string;
-                    break;
-                case START_OBJECT:
-                    value.dateTimeValue = jsonParser.readValueAs(DateTime.class);
-                    break;
-                default: throw new IOException("Cannot deserialize EqualUnion");
-            }
-            return value;
-        }
-    }
-
-    static class Serializer extends JsonSerializer<EqualUnion> {
-        @Override
-        public void serialize(EqualUnion obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-            if (obj.doubleValue != null) {
-                jsonGenerator.writeObject(obj.doubleValue);
-                return;
-            }
-            if (obj.boolValue != null) {
-                jsonGenerator.writeObject(obj.boolValue);
-                return;
-            }
-            if (obj.dateTimeValue != null) {
-                jsonGenerator.writeObject(obj.dateTimeValue);
-                return;
-            }
-            if (obj.stringValue != null) {
-                jsonGenerator.writeObject(obj.stringValue);
-                return;
-            }
-            jsonGenerator.writeNull();
-        }
-    }
-}
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/FacetFieldDef.java b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/FacetFieldDef.java
index ce6a490..6a4b68b 100644
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/FacetFieldDef.java
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/FacetFieldDef.java
@@ -9,7 +9,7 @@ import com.fasterxml.jackson.annotation.*;
  */
 public class FacetFieldDef {
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private Field field;
     private Header header;
     private SortEnum sort;
@@ -35,9 +35,9 @@ public class FacetFieldDef {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * __Required.__ A string defining the name of the field from which to pull a data value
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/FieldDef.java b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/FieldDef.java
index 46826ea..ed0f44b 100644
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/FieldDef.java
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/FieldDef.java
@@ -7,7 +7,7 @@ import com.fasterxml.jackson.annotation.*;
  */
 public class FieldDef {
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private Field field;
     private TimeUnit timeUnit;
     private Type type;
@@ -31,9 +31,9 @@ public class FieldDef {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * __Required.__ A string defining the name of the field from which to pull a data value
diff --git a/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/LogicalOperandPredicate.java b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/LogicalOperandPredicate.java
new file mode 100644
index 0000000..9291af2
--- /dev/null
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/LogicalOperandPredicate.java
@@ -0,0 +1,58 @@
+package io.quicktype;
+
+import java.io.IOException;
+import java.io.IOException;
+import com.fasterxml.jackson.core.*;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.annotation.*;
+import com.fasterxml.jackson.core.type.*;
+
+/**
+ * The `filter` property must be one of the predicate definitions:
+ * (1) an [expression](types.html#expression) string,
+ * where `datum` can be used to refer to the current data object;
+ * (2) one of the field predicates: [equal predicate](filter.html#equal-predicate);
+ * [range predicate](filter.html#range-predicate), [one-of
+ * predicate](filter.html#one-of-predicate);
+ * (3) a [selection predicate](filter.html#selection-predicate);
+ * or (4) a logical operand that combines (1), (2), or (3).
+ */
+@JsonDeserialize(using = LogicalOperandPredicate.Deserializer.class)
+@JsonSerialize(using = LogicalOperandPredicate.Serializer.class)
+public class LogicalOperandPredicate {
+    public Predicate predicateValue;
+    public String stringValue;
+
+    static class Deserializer extends JsonDeserializer<LogicalOperandPredicate> {
+        @Override
+        public LogicalOperandPredicate deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            LogicalOperandPredicate value = new LogicalOperandPredicate();
+            switch (jsonParser.currentToken()) {
+                case VALUE_STRING:
+                    String string = jsonParser.readValueAs(String.class);
+                    value.stringValue = string;
+                    break;
+                case START_OBJECT:
+                    value.predicateValue = jsonParser.readValueAs(Predicate.class);
+                    break;
+                default: throw new IOException("Cannot deserialize LogicalOperandPredicate");
+            }
+            return value;
+        }
+    }
+
+    static class Serializer extends JsonSerializer<LogicalOperandPredicate> {
+        @Override
+        public void serialize(LogicalOperandPredicate obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+            if (obj.predicateValue != null) {
+                jsonGenerator.writeObject(obj.predicateValue);
+                return;
+            }
+            if (obj.stringValue != null) {
+                jsonGenerator.writeObject(obj.stringValue);
+                return;
+            }
+            throw new IOException("LogicalOperandPredicate must not be null");
+        }
+    }
+}
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/LogicalOperandPredicateElement.java b/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/LogicalOperandPredicateElement.java
deleted file mode 100644
index e70cb12..0000000
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/LogicalOperandPredicateElement.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package io.quicktype;
-
-import java.io.IOException;
-import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.annotation.*;
-import com.fasterxml.jackson.core.type.*;
-
-/**
- * The `filter` property must be one of the predicate definitions:
- * (1) an [expression](types.html#expression) string,
- * where `datum` can be used to refer to the current data object;
- * (2) one of the field predicates: [equal predicate](filter.html#equal-predicate);
- * [range predicate](filter.html#range-predicate), [one-of
- * predicate](filter.html#one-of-predicate);
- * (3) a [selection predicate](filter.html#selection-predicate);
- * or (4) a logical operand that combines (1), (2), or (3).
- */
-@JsonDeserialize(using = LogicalOperandPredicateElement.Deserializer.class)
-@JsonSerialize(using = LogicalOperandPredicateElement.Serializer.class)
-public class LogicalOperandPredicateElement {
-    public Predicate predicateValue;
-    public String stringValue;
-
-    static class Deserializer extends JsonDeserializer<LogicalOperandPredicateElement> {
-        @Override
-        public LogicalOperandPredicateElement deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            LogicalOperandPredicateElement value = new LogicalOperandPredicateElement();
-            switch (jsonParser.currentToken()) {
-                case VALUE_STRING:
-                    String string = jsonParser.readValueAs(String.class);
-                    value.stringValue = string;
-                    break;
-                case START_OBJECT:
-                    value.predicateValue = jsonParser.readValueAs(Predicate.class);
-                    break;
-                default: throw new IOException("Cannot deserialize LogicalOperandPredicateElement");
-            }
-            return value;
-        }
-    }
-
-    static class Serializer extends JsonSerializer<LogicalOperandPredicateElement> {
-        @Override
-        public void serialize(LogicalOperandPredicateElement obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-            if (obj.predicateValue != null) {
-                jsonGenerator.writeObject(obj.predicateValue);
-                return;
-            }
-            if (obj.stringValue != null) {
-                jsonGenerator.writeObject(obj.stringValue);
-                return;
-            }
-            throw new IOException("LogicalOperandPredicateElement must not be null");
-        }
-    }
-}
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/MarkPropDefWithCondition.java b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/MarkPropDefWithCondition.java
index c5c5748..796f64b 100644
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/MarkPropDefWithCondition.java
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/MarkPropDefWithCondition.java
@@ -48,7 +48,7 @@ import java.util.List;
  */
 public class MarkPropDefWithCondition {
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private ColorCondition condition;
     private Field field;
     private Legend legend;
@@ -56,7 +56,7 @@ public class MarkPropDefWithCondition {
     private SortUnion sort;
     private TimeUnit timeUnit;
     private Type type;
-    private ConditionalPredicateValueDefValue value;
+    private ColorValue value;
 
     /**
      * Aggregation function for the field
@@ -77,9 +77,9 @@ public class MarkPropDefWithCondition {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * One or more value definition(s) with a selection predicate.
@@ -174,7 +174,7 @@ public class MarkPropDefWithCondition {
      * A constant value in visual domain.
      */
     @JsonProperty("value")
-    public ConditionalPredicateValueDefValue getValue() { return value; }
+    public ColorValue getValue() { return value; }
     @JsonProperty("value")
-    public void setValue(ConditionalPredicateValueDefValue value) { this.value = value; }
+    public void setValue(ColorValue value) { this.value = value; }
 }
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/OneOfElement.java b/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/OneOfElement.java
deleted file mode 100644
index 7e6a5e2..0000000
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/OneOfElement.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package io.quicktype;
-
-import java.io.IOException;
-import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.annotation.*;
-import com.fasterxml.jackson.core.type.*;
-
-/**
- * The value that the field should be equal to.
- */
-@JsonDeserialize(using = OneOfElement.Deserializer.class)
-@JsonSerialize(using = OneOfElement.Serializer.class)
-public class OneOfElement {
-    public Double doubleValue;
-    public Boolean boolValue;
-    public DateTime dateTimeValue;
-    public String stringValue;
-
-    static class Deserializer extends JsonDeserializer<OneOfElement> {
-        @Override
-        public OneOfElement deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            OneOfElement value = new OneOfElement();
-            switch (jsonParser.currentToken()) {
-                case VALUE_NUMBER_INT:
-                case VALUE_NUMBER_FLOAT:
-                    value.doubleValue = jsonParser.readValueAs(Double.class);
-                    break;
-                case VALUE_TRUE:
-                case VALUE_FALSE:
-                    value.boolValue = jsonParser.readValueAs(Boolean.class);
-                    break;
-                case VALUE_STRING:
-                    String string = jsonParser.readValueAs(String.class);
-                    value.stringValue = string;
-                    break;
-                case START_OBJECT:
-                    value.dateTimeValue = jsonParser.readValueAs(DateTime.class);
-                    break;
-                default: throw new IOException("Cannot deserialize OneOfElement");
-            }
-            return value;
-        }
-    }
-
-    static class Serializer extends JsonSerializer<OneOfElement> {
-        @Override
-        public void serialize(OneOfElement obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-            if (obj.doubleValue != null) {
-                jsonGenerator.writeObject(obj.doubleValue);
-                return;
-            }
-            if (obj.boolValue != null) {
-                jsonGenerator.writeObject(obj.boolValue);
-                return;
-            }
-            if (obj.dateTimeValue != null) {
-                jsonGenerator.writeObject(obj.dateTimeValue);
-                return;
-            }
-            if (obj.stringValue != null) {
-                jsonGenerator.writeObject(obj.stringValue);
-                return;
-            }
-            throw new IOException("OneOfElement must not be null");
-        }
-    }
-}
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/OrderFieldDef.java b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/OrderFieldDef.java
index de6d278..28e11ef 100644
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/OrderFieldDef.java
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/OrderFieldDef.java
@@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.*;
 
 public class OrderFieldDef {
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private Field field;
     private SortEnum sort;
     private TimeUnit timeUnit;
@@ -29,9 +29,9 @@ public class OrderFieldDef {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * __Required.__ A string defining the name of the field from which to pull a data value
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Predicate.java b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Predicate.java
index b9c3609..be0e2df 100644
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Predicate.java
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Predicate.java
@@ -4,38 +4,38 @@ import com.fasterxml.jackson.annotation.*;
 import java.util.List;
 
 public class Predicate {
-    private ConditionalValueDefLogicalOperandPredicate not;
-    private List<LogicalOperandPredicateElement> and;
-    private List<LogicalOperandPredicateElement> or;
-    private EqualUnion equal;
+    private LogicalOperandPredicate not;
+    private List<LogicalOperandPredicate> and;
+    private List<LogicalOperandPredicate> or;
+    private Equal equal;
     private String field;
     private TimeUnit timeUnit;
     private List<RangeElement> range;
-    private List<OneOfElement> oneOf;
-    private ConditionalValueDefSelectionOperand selection;
+    private List<Equal> oneOf;
+    private SelectionOperand selection;
 
     @JsonProperty("not")
-    public ConditionalValueDefLogicalOperandPredicate getNot() { return not; }
+    public LogicalOperandPredicate getNot() { return not; }
     @JsonProperty("not")
-    public void setNot(ConditionalValueDefLogicalOperandPredicate value) { this.not = value; }
+    public void setNot(LogicalOperandPredicate value) { this.not = value; }
 
     @JsonProperty("and")
-    public List<LogicalOperandPredicateElement> getAnd() { return and; }
+    public List<LogicalOperandPredicate> getAnd() { return and; }
     @JsonProperty("and")
-    public void setAnd(List<LogicalOperandPredicateElement> value) { this.and = value; }
+    public void setAnd(List<LogicalOperandPredicate> value) { this.and = value; }
 
     @JsonProperty("or")
-    public List<LogicalOperandPredicateElement> getOr() { return or; }
+    public List<LogicalOperandPredicate> getOr() { return or; }
     @JsonProperty("or")
-    public void setOr(List<LogicalOperandPredicateElement> value) { this.or = value; }
+    public void setOr(List<LogicalOperandPredicate> value) { this.or = value; }
 
     /**
      * The value that the field should be equal to.
      */
     @JsonProperty("equal")
-    public EqualUnion getEqual() { return equal; }
+    public Equal getEqual() { return equal; }
     @JsonProperty("equal")
-    public void setEqual(EqualUnion value) { this.equal = value; }
+    public void setEqual(Equal value) { this.equal = value; }
 
     /**
      * Field to be filtered.
@@ -71,15 +71,15 @@ public class Predicate {
      * for a data item included in the filtered data.
      */
     @JsonProperty("oneOf")
-    public List<OneOfElement> getOneOf() { return oneOf; }
+    public List<Equal> getOneOf() { return oneOf; }
     @JsonProperty("oneOf")
-    public void setOneOf(List<OneOfElement> value) { this.oneOf = value; }
+    public void setOneOf(List<Equal> value) { this.oneOf = value; }
 
     /**
      * Filter using a selection name.
      */
     @JsonProperty("selection")
-    public ConditionalValueDefSelectionOperand getSelection() { return selection; }
+    public SelectionOperand getSelection() { return selection; }
     @JsonProperty("selection")
-    public void setSelection(ConditionalValueDefSelectionOperand value) { this.selection = value; }
+    public void setSelection(SelectionOperand value) { this.selection = value; }
 }
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Selection.java b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Selection.java
index 16251b4..0520466 100644
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Selection.java
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Selection.java
@@ -4,22 +4,22 @@ import com.fasterxml.jackson.annotation.*;
 import java.util.List;
 
 public class Selection {
-    private ConditionalValueDefSelectionOperand not;
-    private List<SelectionOperandElement> and;
-    private List<SelectionOperandElement> or;
+    private SelectionOperand not;
+    private List<SelectionOperand> and;
+    private List<SelectionOperand> or;
 
     @JsonProperty("not")
-    public ConditionalValueDefSelectionOperand getNot() { return not; }
+    public SelectionOperand getNot() { return not; }
     @JsonProperty("not")
-    public void setNot(ConditionalValueDefSelectionOperand value) { this.not = value; }
+    public void setNot(SelectionOperand value) { this.not = value; }
 
     @JsonProperty("and")
-    public List<SelectionOperandElement> getAnd() { return and; }
+    public List<SelectionOperand> getAnd() { return and; }
     @JsonProperty("and")
-    public void setAnd(List<SelectionOperandElement> value) { this.and = value; }
+    public void setAnd(List<SelectionOperand> value) { this.and = value; }
 
     @JsonProperty("or")
-    public List<SelectionOperandElement> getOr() { return or; }
+    public List<SelectionOperand> getOr() { return or; }
     @JsonProperty("or")
-    public void setOr(List<SelectionOperandElement> value) { this.or = value; }
+    public void setOr(List<SelectionOperand> value) { this.or = value; }
 }
diff --git a/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/SelectionOperand.java b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/SelectionOperand.java
new file mode 100644
index 0000000..7aa449b
--- /dev/null
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/SelectionOperand.java
@@ -0,0 +1,54 @@
+package io.quicktype;
+
+import java.io.IOException;
+import java.io.IOException;
+import com.fasterxml.jackson.core.*;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.annotation.*;
+import com.fasterxml.jackson.core.type.*;
+
+/**
+ * Filter using a selection name.
+ *
+ * A [selection name](selection.html), or a series of [composed
+ * selections](selection.html#compose).
+ */
+@JsonDeserialize(using = SelectionOperand.Deserializer.class)
+@JsonSerialize(using = SelectionOperand.Serializer.class)
+public class SelectionOperand {
+    public Selection selectionValue;
+    public String stringValue;
+
+    static class Deserializer extends JsonDeserializer<SelectionOperand> {
+        @Override
+        public SelectionOperand deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            SelectionOperand value = new SelectionOperand();
+            switch (jsonParser.currentToken()) {
+                case VALUE_STRING:
+                    String string = jsonParser.readValueAs(String.class);
+                    value.stringValue = string;
+                    break;
+                case START_OBJECT:
+                    value.selectionValue = jsonParser.readValueAs(Selection.class);
+                    break;
+                default: throw new IOException("Cannot deserialize SelectionOperand");
+            }
+            return value;
+        }
+    }
+
+    static class Serializer extends JsonSerializer<SelectionOperand> {
+        @Override
+        public void serialize(SelectionOperand obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+            if (obj.selectionValue != null) {
+                jsonGenerator.writeObject(obj.selectionValue);
+                return;
+            }
+            if (obj.stringValue != null) {
+                jsonGenerator.writeObject(obj.stringValue);
+                return;
+            }
+            throw new IOException("SelectionOperand must not be null");
+        }
+    }
+}
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/SelectionOperandElement.java b/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/SelectionOperandElement.java
deleted file mode 100644
index 269da8d..0000000
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/SelectionOperandElement.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package io.quicktype;
-
-import java.io.IOException;
-import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.annotation.*;
-import com.fasterxml.jackson.core.type.*;
-
-/**
- * Filter using a selection name.
- *
- * A [selection name](selection.html), or a series of [composed
- * selections](selection.html#compose).
- */
-@JsonDeserialize(using = SelectionOperandElement.Deserializer.class)
-@JsonSerialize(using = SelectionOperandElement.Serializer.class)
-public class SelectionOperandElement {
-    public Selection selectionValue;
-    public String stringValue;
-
-    static class Deserializer extends JsonDeserializer<SelectionOperandElement> {
-        @Override
-        public SelectionOperandElement deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            SelectionOperandElement value = new SelectionOperandElement();
-            switch (jsonParser.currentToken()) {
-                case VALUE_STRING:
-                    String string = jsonParser.readValueAs(String.class);
-                    value.stringValue = string;
-                    break;
-                case START_OBJECT:
-                    value.selectionValue = jsonParser.readValueAs(Selection.class);
-                    break;
-                default: throw new IOException("Cannot deserialize SelectionOperandElement");
-            }
-            return value;
-        }
-    }
-
-    static class Serializer extends JsonSerializer<SelectionOperandElement> {
-        @Override
-        public void serialize(SelectionOperandElement obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-            if (obj.selectionValue != null) {
-                jsonGenerator.writeObject(obj.selectionValue);
-                return;
-            }
-            if (obj.stringValue != null) {
-                jsonGenerator.writeObject(obj.stringValue);
-                return;
-            }
-            throw new IOException("SelectionOperandElement must not be null");
-        }
-    }
-}
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/TextDefWithCondition.java b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/TextDefWithCondition.java
index bab354b..5bc625d 100644
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/TextDefWithCondition.java
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/TextDefWithCondition.java
@@ -23,13 +23,13 @@ import java.util.List;
  */
 public class TextDefWithCondition {
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private TextCondition condition;
     private Field field;
     private String format;
     private TimeUnit timeUnit;
     private Type type;
-    private ConditionalPredicateValueDefValue value;
+    private ColorValue value;
 
     /**
      * Aggregation function for the field
@@ -50,9 +50,9 @@ public class TextDefWithCondition {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * One or more value definition(s) with a selection predicate.
@@ -120,7 +120,7 @@ public class TextDefWithCondition {
      * A constant value in visual domain.
      */
     @JsonProperty("value")
-    public ConditionalPredicateValueDefValue getValue() { return value; }
+    public ColorValue getValue() { return value; }
     @JsonProperty("value")
-    public void setValue(ConditionalPredicateValueDefValue value) { this.value = value; }
+    public void setValue(ColorValue value) { this.value = value; }
 }
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Transform.java b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Transform.java
index cbf0ea3..1065f00 100644
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Transform.java
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Transform.java
@@ -4,13 +4,13 @@ import com.fasterxml.jackson.annotation.*;
 import java.util.List;
 
 public class Transform {
-    private ConditionalValueDefLogicalOperandPredicate filter;
+    private LogicalOperandPredicate filter;
     private Style as;
     private String calculate;
     private String transformDefault;
     private LookupData from;
     private String lookup;
-    private Bin bin;
+    private TransformBin bin;
     private String field;
     private TimeUnit timeUnit;
     private List<AggregatedFieldDef> aggregate;
@@ -27,9 +27,9 @@ public class Transform {
      * or (4) a logical operand that combines (1), (2), or (3).
      */
     @JsonProperty("filter")
-    public ConditionalValueDefLogicalOperandPredicate getFilter() { return filter; }
+    public LogicalOperandPredicate getFilter() { return filter; }
     @JsonProperty("filter")
-    public void setFilter(ConditionalValueDefLogicalOperandPredicate value) { this.filter = value; }
+    public void setFilter(LogicalOperandPredicate value) { this.filter = value; }
 
     /**
      * The field for storing the computed formula value.
@@ -87,9 +87,9 @@ public class Transform {
      * An object indicating bin properties, or simply `true` for using default bin parameters.
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public TransformBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(TransformBin value) { this.bin = value; }
 
     /**
      * The data field to bin.
diff --git a/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/TransformBin.java b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/TransformBin.java
new file mode 100644
index 0000000..ae29fc2
--- /dev/null
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/TransformBin.java
@@ -0,0 +1,48 @@
+package io.quicktype;
+
+import java.io.IOException;
+import java.io.IOException;
+import com.fasterxml.jackson.core.*;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.annotation.*;
+import com.fasterxml.jackson.core.type.*;
+
+@JsonDeserialize(using = TransformBin.Deserializer.class)
+@JsonSerialize(using = TransformBin.Serializer.class)
+public class TransformBin {
+    public Boolean boolValue;
+    public BinParams binParamsValue;
+
+    static class Deserializer extends JsonDeserializer<TransformBin> {
+        @Override
+        public TransformBin deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            TransformBin value = new TransformBin();
+            switch (jsonParser.currentToken()) {
+                case VALUE_TRUE:
+                case VALUE_FALSE:
+                    value.boolValue = jsonParser.readValueAs(Boolean.class);
+                    break;
+                case START_OBJECT:
+                    value.binParamsValue = jsonParser.readValueAs(BinParams.class);
+                    break;
+                default: throw new IOException("Cannot deserialize TransformBin");
+            }
+            return value;
+        }
+    }
+
+    static class Serializer extends JsonSerializer<TransformBin> {
+        @Override
+        public void serialize(TransformBin obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+            if (obj.boolValue != null) {
+                jsonGenerator.writeObject(obj.boolValue);
+                return;
+            }
+            if (obj.binParamsValue != null) {
+                jsonGenerator.writeObject(obj.binParamsValue);
+                return;
+            }
+            throw new IOException("TransformBin must not be null");
+        }
+    }
+}
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Values.java b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Values.java
index dc130c0..486b136 100644
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Values.java
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Values.java
@@ -27,8 +27,6 @@ public class Values {
         public Values deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
             Values value = new Values();
             switch (jsonParser.currentToken()) {
-                case VALUE_NULL:
-                    break;
                 case VALUE_STRING:
                     String string = jsonParser.readValueAs(String.class);
                     value.stringValue = string;
@@ -60,7 +58,7 @@ public class Values {
                 jsonGenerator.writeObject(obj.stringValue);
                 return;
             }
-            jsonGenerator.writeNull();
+            throw new IOException("Values must not be null");
         }
     }
 }
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/X2Class.java b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/X2Class.java
index 4742838..38d62b5 100644
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/X2Class.java
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/X2Class.java
@@ -13,11 +13,11 @@ import com.fasterxml.jackson.annotation.*;
  */
 public class X2Class {
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private Field field;
     private TimeUnit timeUnit;
     private Type type;
-    private ConditionalPredicateValueDefValue value;
+    private ConditionalValueDefValue value;
 
     /**
      * Aggregation function for the field
@@ -38,9 +38,9 @@ public class X2Class {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * __Required.__ A string defining the name of the field from which to pull a data value
@@ -86,7 +86,7 @@ public class X2Class {
      * `0` to `1` for opacity).
      */
     @JsonProperty("value")
-    public ConditionalPredicateValueDefValue getValue() { return value; }
+    public ConditionalValueDefValue getValue() { return value; }
     @JsonProperty("value")
-    public void setValue(ConditionalPredicateValueDefValue value) { this.value = value; }
+    public void setValue(ConditionalValueDefValue value) { this.value = value; }
 }
diff --git a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/XClass.java b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/XClass.java
index 38c4a64..c71f712 100644
--- a/base/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/XClass.java
+++ b/head/schema-java-datetime-legacy/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/XClass.java
@@ -12,14 +12,14 @@ import com.fasterxml.jackson.annotation.*;
 public class XClass {
     private AggregateOp aggregate;
     private Axis axis;
-    private Bin bin;
+    private ColorBin bin;
     private Field field;
     private Scale scale;
     private SortUnion sort;
     private StackOffset stack;
     private TimeUnit timeUnit;
     private Type type;
-    private ConditionalPredicateValueDefValue value;
+    private ConditionalValueDefValue value;
 
     /**
      * Aggregation function for the field
@@ -51,9 +51,9 @@ public class XClass {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * __Required.__ A string defining the name of the field from which to pull a data value
@@ -151,7 +151,7 @@ public class XClass {
      * `0` to `1` for opacity).
      */
     @JsonProperty("value")
-    public ConditionalPredicateValueDefValue getValue() { return value; }
+    public ConditionalValueDefValue getValue() { return value; }
     @JsonProperty("value")
-    public void setValue(ConditionalPredicateValueDefValue value) { this.value = value; }
+    public void setValue(ConditionalValueDefValue value) { this.value = value; }
 }
diff --git a/head/schema-java-lombok/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/Anyof.java b/head/schema-java-lombok/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/Anyof.java
new file mode 100644
index 0000000..500bdc2
--- /dev/null
+++ b/head/schema-java-lombok/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/Anyof.java
@@ -0,0 +1,18 @@
+package io.quicktype;
+
+import com.fasterxml.jackson.annotation.*;
+
+public class Anyof {
+    private String name;
+    private String size;
+
+    @JsonProperty("name")
+    public String getName() { return name; }
+    @JsonProperty("name")
+    public void setName(String value) { this.name = value; }
+
+    @JsonProperty("size")
+    public String getSize() { return size; }
+    @JsonProperty("size")
+    public void setSize(String value) { this.size = value; }
+}
diff --git a/head/schema-java-lombok/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/Converter.java b/head/schema-java-lombok/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/Converter.java
new file mode 100644
index 0000000..a8eb236
--- /dev/null
+++ b/head/schema-java-lombok/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/Converter.java
@@ -0,0 +1,101 @@
+// To use this code, add the following Maven dependency to your project:
+//
+//
+//     com.fasterxml.jackson.core     : jackson-databind          : 2.9.0
+//     com.fasterxml.jackson.datatype : jackson-datatype-jsr310   : 2.9.0
+//
+// Import this package:
+//
+//     import io.quicktype.Converter;
+//
+// Then you can deserialize a JSON string with
+//
+//     TopLevel data = Converter.fromJsonString(jsonString);
+
+package io.quicktype;
+
+import java.io.IOException;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import java.util.*;
+import java.time.LocalDate;
+import java.time.OffsetDateTime;
+import java.time.OffsetTime;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.temporal.ChronoField;
+
+public class Converter {
+    // Date-time helpers
+
+    private static final DateTimeFormatter DATE_TIME_FORMATTER = new DateTimeFormatterBuilder()
+            .appendOptional(DateTimeFormatter.ISO_DATE_TIME)
+            .appendOptional(DateTimeFormatter.ISO_OFFSET_DATE_TIME)
+            .appendOptional(DateTimeFormatter.ISO_INSTANT)
+            .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SX"))
+            .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ssX"))
+            .appendOptional(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
+            .toFormatter()
+            .withZone(ZoneOffset.UTC);
+
+    public static OffsetDateTime parseDateTimeString(String str) {
+        return ZonedDateTime.from(Converter.DATE_TIME_FORMATTER.parse(str)).toOffsetDateTime();
+    }
+
+    private static final DateTimeFormatter TIME_FORMATTER = new DateTimeFormatterBuilder()
+            .appendOptional(DateTimeFormatter.ISO_TIME)
+            .appendOptional(DateTimeFormatter.ISO_OFFSET_TIME)
+            .parseDefaulting(ChronoField.YEAR, 2020)
+            .parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
+            .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
+            .toFormatter()
+            .withZone(ZoneOffset.UTC);
+
+    public static OffsetTime parseTimeString(String str) {
+        return ZonedDateTime.from(Converter.TIME_FORMATTER.parse(str)).toOffsetDateTime().toOffsetTime();
+    }
+    // Serialize/deserialize helpers
+
+    public static TopLevel fromJsonString(String json) throws IOException {
+        return getObjectReader().readValue(json);
+    }
+
+    public static String toJsonString(TopLevel obj) throws JsonProcessingException {
+        return getObjectWriter().writeValueAsString(obj);
+    }
+
+    private static ObjectReader reader;
+    private static ObjectWriter writer;
+
+    private static void instantiateMapper() {
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.findAndRegisterModules();
+        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
+        SimpleModule module = new SimpleModule();
+        module.addDeserializer(OffsetDateTime.class, new JsonDeserializer<OffsetDateTime>() {
+            @Override
+            public OffsetDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+                String value = jsonParser.getText();
+                return Converter.parseDateTimeString(value);
+            }
+        });
+        mapper.registerModule(module);
+        reader = mapper.readerFor(TopLevel.class);
+        writer = mapper.writerFor(TopLevel.class);
+    }
+
+    private static ObjectReader getObjectReader() {
+        if (reader == null) instantiateMapper();
+        return reader;
+    }
+
+    private static ObjectWriter getObjectWriter() {
+        if (writer == null) instantiateMapper();
+        return writer;
+    }
+}
diff --git a/head/schema-java-lombok/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/TopLevel.java b/head/schema-java-lombok/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/TopLevel.java
new file mode 100644
index 0000000..b180d63
--- /dev/null
+++ b/head/schema-java-lombok/test/inputs/schema/required-in-any-of.schema/default/src/main/java/io/quicktype/TopLevel.java
@@ -0,0 +1,12 @@
+package io.quicktype;
+
+import com.fasterxml.jackson.annotation.*;
+
+public class TopLevel {
+    private Anyof anyof;
+
+    @JsonProperty("anyof")
+    public Anyof getAnyof() { return anyof; }
+    @JsonProperty("anyof")
+    public void setAnyof(Anyof value) { this.anyof = value; }
+}
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/AnyMark.java b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/AnyMark.java
index 7ffb7ef..ff16a90 100644
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/AnyMark.java
+++ b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/AnyMark.java
@@ -24,8 +24,6 @@ public class AnyMark {
         public AnyMark deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
             AnyMark value = new AnyMark();
             switch (jsonParser.currentToken()) {
-                case VALUE_NULL:
-                    break;
                 case VALUE_STRING:
                     String string = jsonParser.readValueAs(String.class);
                     try {
@@ -54,7 +52,7 @@ public class AnyMark {
                 jsonGenerator.writeObject(obj.enumValue);
                 return;
             }
-            jsonGenerator.writeNull();
+            throw new IOException("AnyMark must not be null");
         }
     }
 }
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Bin.java b/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Bin.java
deleted file mode 100644
index f2b4b13..0000000
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Bin.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package io.quicktype;
-
-import java.io.IOException;
-import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.annotation.*;
-import com.fasterxml.jackson.core.type.*;
-
-@JsonDeserialize(using = Bin.Deserializer.class)
-@JsonSerialize(using = Bin.Serializer.class)
-public class Bin {
-    public Boolean boolValue;
-    public BinParams binParamsValue;
-
-    static class Deserializer extends JsonDeserializer<Bin> {
-        @Override
-        public Bin deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            Bin value = new Bin();
-            switch (jsonParser.currentToken()) {
-                case VALUE_NULL:
-                    break;
-                case VALUE_TRUE:
-                case VALUE_FALSE:
-                    value.boolValue = jsonParser.readValueAs(Boolean.class);
-                    break;
-                case START_OBJECT:
-                    value.binParamsValue = jsonParser.readValueAs(BinParams.class);
-                    break;
-                default: throw new IOException("Cannot deserialize Bin");
-            }
-            return value;
-        }
-    }
-
-    static class Serializer extends JsonSerializer<Bin> {
-        @Override
-        public void serialize(Bin obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-            if (obj.boolValue != null) {
-                jsonGenerator.writeObject(obj.boolValue);
-                return;
-            }
-            if (obj.binParamsValue != null) {
-                jsonGenerator.writeObject(obj.binParamsValue);
-                return;
-            }
-            jsonGenerator.writeNull();
-        }
-    }
-}
diff --git a/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ColorBin.java b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ColorBin.java
new file mode 100644
index 0000000..ba25f2a
--- /dev/null
+++ b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ColorBin.java
@@ -0,0 +1,50 @@
+package io.quicktype;
+
+import java.io.IOException;
+import java.io.IOException;
+import com.fasterxml.jackson.core.*;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.annotation.*;
+import com.fasterxml.jackson.core.type.*;
+
+@JsonDeserialize(using = ColorBin.Deserializer.class)
+@JsonSerialize(using = ColorBin.Serializer.class)
+public class ColorBin {
+    public Boolean boolValue;
+    public BinParams binParamsValue;
+
+    static class Deserializer extends JsonDeserializer<ColorBin> {
+        @Override
+        public ColorBin deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            ColorBin value = new ColorBin();
+            switch (jsonParser.currentToken()) {
+                case VALUE_NULL:
+                    break;
+                case VALUE_TRUE:
+                case VALUE_FALSE:
+                    value.boolValue = jsonParser.readValueAs(Boolean.class);
+                    break;
+                case START_OBJECT:
+                    value.binParamsValue = jsonParser.readValueAs(BinParams.class);
+                    break;
+                default: throw new IOException("Cannot deserialize ColorBin");
+            }
+            return value;
+        }
+    }
+
+    static class Serializer extends JsonSerializer<ColorBin> {
+        @Override
+        public void serialize(ColorBin obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+            if (obj.boolValue != null) {
+                jsonGenerator.writeObject(obj.boolValue);
+                return;
+            }
+            if (obj.binParamsValue != null) {
+                jsonGenerator.writeObject(obj.binParamsValue);
+                return;
+            }
+            jsonGenerator.writeNull();
+        }
+    }
+}
diff --git a/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ColorValue.java b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ColorValue.java
new file mode 100644
index 0000000..bb6fb5b
--- /dev/null
+++ b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ColorValue.java
@@ -0,0 +1,66 @@
+package io.quicktype;
+
+import java.io.IOException;
+import java.io.IOException;
+import com.fasterxml.jackson.core.*;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.annotation.*;
+import com.fasterxml.jackson.core.type.*;
+
+/**
+ * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
+ * `0` to `1` for opacity).
+ *
+ * A constant value in visual domain.
+ */
+@JsonDeserialize(using = ColorValue.Deserializer.class)
+@JsonSerialize(using = ColorValue.Serializer.class)
+public class ColorValue {
+    public Double doubleValue;
+    public Boolean boolValue;
+    public String stringValue;
+
+    static class Deserializer extends JsonDeserializer<ColorValue> {
+        @Override
+        public ColorValue deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            ColorValue value = new ColorValue();
+            switch (jsonParser.currentToken()) {
+                case VALUE_NULL:
+                    break;
+                case VALUE_NUMBER_INT:
+                case VALUE_NUMBER_FLOAT:
+                    value.doubleValue = jsonParser.readValueAs(Double.class);
+                    break;
+                case VALUE_TRUE:
+                case VALUE_FALSE:
+                    value.boolValue = jsonParser.readValueAs(Boolean.class);
+                    break;
+                case VALUE_STRING:
+                    String string = jsonParser.readValueAs(String.class);
+                    value.stringValue = string;
+                    break;
+                default: throw new IOException("Cannot deserialize ColorValue");
+            }
+            return value;
+        }
+    }
+
+    static class Serializer extends JsonSerializer<ColorValue> {
+        @Override
+        public void serialize(ColorValue obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+            if (obj.doubleValue != null) {
+                jsonGenerator.writeObject(obj.doubleValue);
+                return;
+            }
+            if (obj.boolValue != null) {
+                jsonGenerator.writeObject(obj.boolValue);
+                return;
+            }
+            if (obj.stringValue != null) {
+                jsonGenerator.writeObject(obj.stringValue);
+                return;
+            }
+            jsonGenerator.writeNull();
+        }
+    }
+}
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateFieldDefClass.java b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateFieldDefClass.java
index 0ee72f6..d883001 100644
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateFieldDefClass.java
+++ b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateFieldDefClass.java
@@ -3,37 +3,37 @@ package io.quicktype;
 import com.fasterxml.jackson.annotation.*;
 
 public class ConditionalPredicateFieldDefClass {
-    private ConditionalValueDefLogicalOperandPredicate test;
-    private ConditionalPredicateValueDefValue value;
-    private ConditionalValueDefSelectionOperand selection;
+    private LogicalOperandPredicate test;
+    private ConditionalValueDefValue value;
+    private SelectionOperand selection;
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private Field field;
     private TimeUnit timeUnit;
     private Type type;
 
     @JsonProperty("test")
-    public ConditionalValueDefLogicalOperandPredicate getTest() { return test; }
+    public LogicalOperandPredicate getTest() { return test; }
     @JsonProperty("test")
-    public void setTest(ConditionalValueDefLogicalOperandPredicate value) { this.test = value; }
+    public void setTest(LogicalOperandPredicate value) { this.test = value; }
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
     @JsonProperty("value")
-    public ConditionalPredicateValueDefValue getValue() { return value; }
+    public ConditionalValueDefValue getValue() { return value; }
     @JsonProperty("value")
-    public void setValue(ConditionalPredicateValueDefValue value) { this.value = value; }
+    public void setValue(ConditionalValueDefValue value) { this.value = value; }
 
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
     @JsonProperty("selection")
-    public ConditionalValueDefSelectionOperand getSelection() { return selection; }
+    public SelectionOperand getSelection() { return selection; }
     @JsonProperty("selection")
-    public void setSelection(ConditionalValueDefSelectionOperand value) { this.selection = value; }
+    public void setSelection(SelectionOperand value) { this.selection = value; }
 
     /**
      * Aggregation function for the field
@@ -54,9 +54,9 @@ public class ConditionalPredicateFieldDefClass {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * __Required.__ A string defining the name of the field from which to pull a data value
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateMarkPropFieldDefClass.java b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateMarkPropFieldDefClass.java
index bd46210..cf72cce 100644
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateMarkPropFieldDefClass.java
+++ b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateMarkPropFieldDefClass.java
@@ -3,11 +3,11 @@ package io.quicktype;
 import com.fasterxml.jackson.annotation.*;
 
 public class ConditionalPredicateMarkPropFieldDefClass {
-    private ConditionalValueDefLogicalOperandPredicate test;
-    private ConditionalPredicateValueDefValue value;
-    private ConditionalValueDefSelectionOperand selection;
+    private LogicalOperandPredicate test;
+    private ConditionalValueDefValue value;
+    private SelectionOperand selection;
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private Field field;
     private Legend legend;
     private Scale scale;
@@ -16,27 +16,27 @@ public class ConditionalPredicateMarkPropFieldDefClass {
     private Type type;
 
     @JsonProperty("test")
-    public ConditionalValueDefLogicalOperandPredicate getTest() { return test; }
+    public LogicalOperandPredicate getTest() { return test; }
     @JsonProperty("test")
-    public void setTest(ConditionalValueDefLogicalOperandPredicate value) { this.test = value; }
+    public void setTest(LogicalOperandPredicate value) { this.test = value; }
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
     @JsonProperty("value")
-    public ConditionalPredicateValueDefValue getValue() { return value; }
+    public ConditionalValueDefValue getValue() { return value; }
     @JsonProperty("value")
-    public void setValue(ConditionalPredicateValueDefValue value) { this.value = value; }
+    public void setValue(ConditionalValueDefValue value) { this.value = value; }
 
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
     @JsonProperty("selection")
-    public ConditionalValueDefSelectionOperand getSelection() { return selection; }
+    public SelectionOperand getSelection() { return selection; }
     @JsonProperty("selection")
-    public void setSelection(ConditionalValueDefSelectionOperand value) { this.selection = value; }
+    public void setSelection(SelectionOperand value) { this.selection = value; }
 
     /**
      * Aggregation function for the field
@@ -57,9 +57,9 @@ public class ConditionalPredicateMarkPropFieldDefClass {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * __Required.__ A string defining the name of the field from which to pull a data value
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateTextFieldDefClass.java b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateTextFieldDefClass.java
index eafdc1a..8141189 100644
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateTextFieldDefClass.java
+++ b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateTextFieldDefClass.java
@@ -3,38 +3,38 @@ package io.quicktype;
 import com.fasterxml.jackson.annotation.*;
 
 public class ConditionalPredicateTextFieldDefClass {
-    private ConditionalValueDefLogicalOperandPredicate test;
-    private ConditionalPredicateValueDefValue value;
-    private ConditionalValueDefSelectionOperand selection;
+    private LogicalOperandPredicate test;
+    private ConditionalValueDefValue value;
+    private SelectionOperand selection;
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private Field field;
     private String format;
     private TimeUnit timeUnit;
     private Type type;
 
     @JsonProperty("test")
-    public ConditionalValueDefLogicalOperandPredicate getTest() { return test; }
+    public LogicalOperandPredicate getTest() { return test; }
     @JsonProperty("test")
-    public void setTest(ConditionalValueDefLogicalOperandPredicate value) { this.test = value; }
+    public void setTest(LogicalOperandPredicate value) { this.test = value; }
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
     @JsonProperty("value")
-    public ConditionalPredicateValueDefValue getValue() { return value; }
+    public ConditionalValueDefValue getValue() { return value; }
     @JsonProperty("value")
-    public void setValue(ConditionalPredicateValueDefValue value) { this.value = value; }
+    public void setValue(ConditionalValueDefValue value) { this.value = value; }
 
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
     @JsonProperty("selection")
-    public ConditionalValueDefSelectionOperand getSelection() { return selection; }
+    public SelectionOperand getSelection() { return selection; }
     @JsonProperty("selection")
-    public void setSelection(ConditionalValueDefSelectionOperand value) { this.selection = value; }
+    public void setSelection(SelectionOperand value) { this.selection = value; }
 
     /**
      * Aggregation function for the field
@@ -55,9 +55,9 @@ public class ConditionalPredicateTextFieldDefClass {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * __Required.__ A string defining the name of the field from which to pull a data value
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateValueDefValue.java b/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateValueDefValue.java
deleted file mode 100644
index fe41fbe..0000000
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalPredicateValueDefValue.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package io.quicktype;
-
-import java.io.IOException;
-import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.annotation.*;
-import com.fasterxml.jackson.core.type.*;
-
-/**
- * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
- * `0` to `1` for opacity).
- *
- * A constant value in visual domain.
- */
-@JsonDeserialize(using = ConditionalPredicateValueDefValue.Deserializer.class)
-@JsonSerialize(using = ConditionalPredicateValueDefValue.Serializer.class)
-public class ConditionalPredicateValueDefValue {
-    public Double doubleValue;
-    public Boolean boolValue;
-    public String stringValue;
-
-    static class Deserializer extends JsonDeserializer<ConditionalPredicateValueDefValue> {
-        @Override
-        public ConditionalPredicateValueDefValue deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            ConditionalPredicateValueDefValue value = new ConditionalPredicateValueDefValue();
-            switch (jsonParser.currentToken()) {
-                case VALUE_NULL:
-                    break;
-                case VALUE_NUMBER_INT:
-                case VALUE_NUMBER_FLOAT:
-                    value.doubleValue = jsonParser.readValueAs(Double.class);
-                    break;
-                case VALUE_TRUE:
-                case VALUE_FALSE:
-                    value.boolValue = jsonParser.readValueAs(Boolean.class);
-                    break;
-                case VALUE_STRING:
-                    String string = jsonParser.readValueAs(String.class);
-                    value.stringValue = string;
-                    break;
-                default: throw new IOException("Cannot deserialize ConditionalPredicateValueDefValue");
-            }
-            return value;
-        }
-    }
-
-    static class Serializer extends JsonSerializer<ConditionalPredicateValueDefValue> {
-        @Override
-        public void serialize(ConditionalPredicateValueDefValue obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-            if (obj.doubleValue != null) {
-                jsonGenerator.writeObject(obj.doubleValue);
-                return;
-            }
-            if (obj.boolValue != null) {
-                jsonGenerator.writeObject(obj.boolValue);
-                return;
-            }
-            if (obj.stringValue != null) {
-                jsonGenerator.writeObject(obj.stringValue);
-                return;
-            }
-            jsonGenerator.writeNull();
-        }
-    }
-}
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDef.java b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDef.java
index d11e6b0..4853170 100644
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDef.java
+++ b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDef.java
@@ -3,14 +3,14 @@ package io.quicktype;
 import com.fasterxml.jackson.annotation.*;
 
 public class ConditionalValueDef {
-    private ConditionalValueDefLogicalOperandPredicate test;
+    private LogicalOperandPredicate test;
     private ConditionalValueDefValue value;
-    private ConditionalValueDefSelectionOperand selection;
+    private SelectionOperand selection;
 
     @JsonProperty("test")
-    public ConditionalValueDefLogicalOperandPredicate getTest() { return test; }
+    public LogicalOperandPredicate getTest() { return test; }
     @JsonProperty("test")
-    public void setTest(ConditionalValueDefLogicalOperandPredicate value) { this.test = value; }
+    public void setTest(LogicalOperandPredicate value) { this.test = value; }
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
@@ -26,7 +26,7 @@ public class ConditionalValueDef {
      * selections](selection.html#compose).
      */
     @JsonProperty("selection")
-    public ConditionalValueDefSelectionOperand getSelection() { return selection; }
+    public SelectionOperand getSelection() { return selection; }
     @JsonProperty("selection")
-    public void setSelection(ConditionalValueDefSelectionOperand value) { this.selection = value; }
+    public void setSelection(SelectionOperand value) { this.selection = value; }
 }
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDefLogicalOperandPredicate.java b/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDefLogicalOperandPredicate.java
deleted file mode 100644
index f4bf576..0000000
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDefLogicalOperandPredicate.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package io.quicktype;
-
-import java.io.IOException;
-import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.annotation.*;
-import com.fasterxml.jackson.core.type.*;
-
-/**
- * The `filter` property must be one of the predicate definitions:
- * (1) an [expression](types.html#expression) string,
- * where `datum` can be used to refer to the current data object;
- * (2) one of the field predicates: [equal predicate](filter.html#equal-predicate);
- * [range predicate](filter.html#range-predicate), [one-of
- * predicate](filter.html#one-of-predicate);
- * (3) a [selection predicate](filter.html#selection-predicate);
- * or (4) a logical operand that combines (1), (2), or (3).
- */
-@JsonDeserialize(using = ConditionalValueDefLogicalOperandPredicate.Deserializer.class)
-@JsonSerialize(using = ConditionalValueDefLogicalOperandPredicate.Serializer.class)
-public class ConditionalValueDefLogicalOperandPredicate {
-    public Predicate predicateValue;
-    public String stringValue;
-
-    static class Deserializer extends JsonDeserializer<ConditionalValueDefLogicalOperandPredicate> {
-        @Override
-        public ConditionalValueDefLogicalOperandPredicate deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            ConditionalValueDefLogicalOperandPredicate value = new ConditionalValueDefLogicalOperandPredicate();
-            switch (jsonParser.currentToken()) {
-                case VALUE_NULL:
-                    break;
-                case VALUE_STRING:
-                    String string = jsonParser.readValueAs(String.class);
-                    value.stringValue = string;
-                    break;
-                case START_OBJECT:
-                    value.predicateValue = jsonParser.readValueAs(Predicate.class);
-                    break;
-                default: throw new IOException("Cannot deserialize ConditionalValueDefLogicalOperandPredicate");
-            }
-            return value;
-        }
-    }
-
-    static class Serializer extends JsonSerializer<ConditionalValueDefLogicalOperandPredicate> {
-        @Override
-        public void serialize(ConditionalValueDefLogicalOperandPredicate obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-            if (obj.predicateValue != null) {
-                jsonGenerator.writeObject(obj.predicateValue);
-                return;
-            }
-            if (obj.stringValue != null) {
-                jsonGenerator.writeObject(obj.stringValue);
-                return;
-            }
-            jsonGenerator.writeNull();
-        }
-    }
-}
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDefSelectionOperand.java b/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDefSelectionOperand.java
deleted file mode 100644
index 3ee477d..0000000
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/ConditionalValueDefSelectionOperand.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package io.quicktype;
-
-import java.io.IOException;
-import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.annotation.*;
-import com.fasterxml.jackson.core.type.*;
-
-/**
- * Filter using a selection name.
- *
- * A [selection name](selection.html), or a series of [composed
- * selections](selection.html#compose).
- */
-@JsonDeserialize(using = ConditionalValueDefSelectionOperand.Deserializer.class)
-@JsonSerialize(using = ConditionalValueDefSelectionOperand.Serializer.class)
-public class ConditionalValueDefSelectionOperand {
-    public Selection selectionValue;
-    public String stringValue;
-
-    static class Deserializer extends JsonDeserializer<ConditionalValueDefSelectionOperand> {
-        @Override
-        public ConditionalValueDefSelectionOperand deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            ConditionalValueDefSelectionOperand value = new ConditionalValueDefSelectionOperand();
-            switch (jsonParser.currentToken()) {
-                case VALUE_NULL:
-                    break;
-                case VALUE_STRING:
-                    String string = jsonParser.readValueAs(String.class);
-                    value.stringValue = string;
-                    break;
-                case START_OBJECT:
-                    value.selectionValue = jsonParser.readValueAs(Selection.class);
-                    break;
-                default: throw new IOException("Cannot deserialize ConditionalValueDefSelectionOperand");
-            }
-            return value;
-        }
-    }
-
-    static class Serializer extends JsonSerializer<ConditionalValueDefSelectionOperand> {
-        @Override
-        public void serialize(ConditionalValueDefSelectionOperand obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-            if (obj.selectionValue != null) {
-                jsonGenerator.writeObject(obj.selectionValue);
-                return;
-            }
-            if (obj.stringValue != null) {
-                jsonGenerator.writeObject(obj.stringValue);
-                return;
-            }
-            jsonGenerator.writeNull();
-        }
-    }
-}
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/DefWithCondition.java b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/DefWithCondition.java
index d044c42..19c0bbb 100644
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/DefWithCondition.java
+++ b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/DefWithCondition.java
@@ -21,12 +21,12 @@ import java.util.List;
  */
 public class DefWithCondition {
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private HrefCondition condition;
     private Field field;
     private TimeUnit timeUnit;
     private Type type;
-    private ConditionalPredicateValueDefValue value;
+    private ColorValue value;
 
     /**
      * Aggregation function for the field
@@ -47,9 +47,9 @@ public class DefWithCondition {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * One or more value definition(s) with a selection predicate.
@@ -108,7 +108,7 @@ public class DefWithCondition {
      * A constant value in visual domain.
      */
     @JsonProperty("value")
-    public ConditionalPredicateValueDefValue getValue() { return value; }
+    public ColorValue getValue() { return value; }
     @JsonProperty("value")
-    public void setValue(ConditionalPredicateValueDefValue value) { this.value = value; }
+    public void setValue(ColorValue value) { this.value = value; }
 }
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/DomainUnion.java b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/DomainUnion.java
index e70f578..0f19e22 100644
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/DomainUnion.java
+++ b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/DomainUnion.java
@@ -29,7 +29,7 @@ import java.util.List;
 @JsonDeserialize(using = DomainUnion.Deserializer.class)
 @JsonSerialize(using = DomainUnion.Serializer.class)
 public class DomainUnion {
-    public List<OneOfElement> unionArrayValue;
+    public List<Equal> unionArrayValue;
     public DomainClass domainClassValue;
     public Domain enumValue;
 
@@ -49,7 +49,7 @@ public class DomainUnion {
                     }
                     break;
                 case START_ARRAY:
-                    value.unionArrayValue = jsonParser.readValueAs(new TypeReference<List<OneOfElement>>() {});
+                    value.unionArrayValue = jsonParser.readValueAs(new TypeReference<List<Equal>>() {});
                     break;
                 case START_OBJECT:
                     value.domainClassValue = jsonParser.readValueAs(DomainClass.class);
diff --git a/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Equal.java b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Equal.java
new file mode 100644
index 0000000..9254aa8
--- /dev/null
+++ b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Equal.java
@@ -0,0 +1,69 @@
+package io.quicktype;
+
+import java.io.IOException;
+import java.io.IOException;
+import com.fasterxml.jackson.core.*;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.annotation.*;
+import com.fasterxml.jackson.core.type.*;
+
+/**
+ * The value that the field should be equal to.
+ */
+@JsonDeserialize(using = Equal.Deserializer.class)
+@JsonSerialize(using = Equal.Serializer.class)
+public class Equal {
+    public Double doubleValue;
+    public Boolean boolValue;
+    public DateTime dateTimeValue;
+    public String stringValue;
+
+    static class Deserializer extends JsonDeserializer<Equal> {
+        @Override
+        public Equal deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            Equal value = new Equal();
+            switch (jsonParser.currentToken()) {
+                case VALUE_NUMBER_INT:
+                case VALUE_NUMBER_FLOAT:
+                    value.doubleValue = jsonParser.readValueAs(Double.class);
+                    break;
+                case VALUE_TRUE:
+                case VALUE_FALSE:
+                    value.boolValue = jsonParser.readValueAs(Boolean.class);
+                    break;
+                case VALUE_STRING:
+                    String string = jsonParser.readValueAs(String.class);
+                    value.stringValue = string;
+                    break;
+                case START_OBJECT:
+                    value.dateTimeValue = jsonParser.readValueAs(DateTime.class);
+                    break;
+                default: throw new IOException("Cannot deserialize Equal");
+            }
+            return value;
+        }
+    }
+
+    static class Serializer extends JsonSerializer<Equal> {
+        @Override
+        public void serialize(Equal obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+            if (obj.doubleValue != null) {
+                jsonGenerator.writeObject(obj.doubleValue);
+                return;
+            }
+            if (obj.boolValue != null) {
+                jsonGenerator.writeObject(obj.boolValue);
+                return;
+            }
+            if (obj.dateTimeValue != null) {
+                jsonGenerator.writeObject(obj.dateTimeValue);
+                return;
+            }
+            if (obj.stringValue != null) {
+                jsonGenerator.writeObject(obj.stringValue);
+                return;
+            }
+            throw new IOException("Equal must not be null");
+        }
+    }
+}
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/EqualUnion.java b/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/EqualUnion.java
deleted file mode 100644
index cde8d77..0000000
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/EqualUnion.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package io.quicktype;
-
-import java.io.IOException;
-import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.annotation.*;
-import com.fasterxml.jackson.core.type.*;
-
-/**
- * The value that the field should be equal to.
- */
-@JsonDeserialize(using = EqualUnion.Deserializer.class)
-@JsonSerialize(using = EqualUnion.Serializer.class)
-public class EqualUnion {
-    public Double doubleValue;
-    public Boolean boolValue;
-    public DateTime dateTimeValue;
-    public String stringValue;
-
-    static class Deserializer extends JsonDeserializer<EqualUnion> {
-        @Override
-        public EqualUnion deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            EqualUnion value = new EqualUnion();
-            switch (jsonParser.currentToken()) {
-                case VALUE_NULL:
-                    break;
-                case VALUE_NUMBER_INT:
-                case VALUE_NUMBER_FLOAT:
-                    value.doubleValue = jsonParser.readValueAs(Double.class);
-                    break;
-                case VALUE_TRUE:
-                case VALUE_FALSE:
-                    value.boolValue = jsonParser.readValueAs(Boolean.class);
-                    break;
-                case VALUE_STRING:
-                    String string = jsonParser.readValueAs(String.class);
-                    value.stringValue = string;
-                    break;
-                case START_OBJECT:
-                    value.dateTimeValue = jsonParser.readValueAs(DateTime.class);
-                    break;
-                default: throw new IOException("Cannot deserialize EqualUnion");
-            }
-            return value;
-        }
-    }
-
-    static class Serializer extends JsonSerializer<EqualUnion> {
-        @Override
-        public void serialize(EqualUnion obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-            if (obj.doubleValue != null) {
-                jsonGenerator.writeObject(obj.doubleValue);
-                return;
-            }
-            if (obj.boolValue != null) {
-                jsonGenerator.writeObject(obj.boolValue);
-                return;
-            }
-            if (obj.dateTimeValue != null) {
-                jsonGenerator.writeObject(obj.dateTimeValue);
-                return;
-            }
-            if (obj.stringValue != null) {
-                jsonGenerator.writeObject(obj.stringValue);
-                return;
-            }
-            jsonGenerator.writeNull();
-        }
-    }
-}
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/FacetFieldDef.java b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/FacetFieldDef.java
index ce6a490..6a4b68b 100644
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/FacetFieldDef.java
+++ b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/FacetFieldDef.java
@@ -9,7 +9,7 @@ import com.fasterxml.jackson.annotation.*;
  */
 public class FacetFieldDef {
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private Field field;
     private Header header;
     private SortEnum sort;
@@ -35,9 +35,9 @@ public class FacetFieldDef {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * __Required.__ A string defining the name of the field from which to pull a data value
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/FieldDef.java b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/FieldDef.java
index 46826ea..ed0f44b 100644
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/FieldDef.java
+++ b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/FieldDef.java
@@ -7,7 +7,7 @@ import com.fasterxml.jackson.annotation.*;
  */
 public class FieldDef {
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private Field field;
     private TimeUnit timeUnit;
     private Type type;
@@ -31,9 +31,9 @@ public class FieldDef {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * __Required.__ A string defining the name of the field from which to pull a data value
diff --git a/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/LogicalOperandPredicate.java b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/LogicalOperandPredicate.java
new file mode 100644
index 0000000..9291af2
--- /dev/null
+++ b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/LogicalOperandPredicate.java
@@ -0,0 +1,58 @@
+package io.quicktype;
+
+import java.io.IOException;
+import java.io.IOException;
+import com.fasterxml.jackson.core.*;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.annotation.*;
+import com.fasterxml.jackson.core.type.*;
+
+/**
+ * The `filter` property must be one of the predicate definitions:
+ * (1) an [expression](types.html#expression) string,
+ * where `datum` can be used to refer to the current data object;
+ * (2) one of the field predicates: [equal predicate](filter.html#equal-predicate);
+ * [range predicate](filter.html#range-predicate), [one-of
+ * predicate](filter.html#one-of-predicate);
+ * (3) a [selection predicate](filter.html#selection-predicate);
+ * or (4) a logical operand that combines (1), (2), or (3).
+ */
+@JsonDeserialize(using = LogicalOperandPredicate.Deserializer.class)
+@JsonSerialize(using = LogicalOperandPredicate.Serializer.class)
+public class LogicalOperandPredicate {
+    public Predicate predicateValue;
+    public String stringValue;
+
+    static class Deserializer extends JsonDeserializer<LogicalOperandPredicate> {
+        @Override
+        public LogicalOperandPredicate deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            LogicalOperandPredicate value = new LogicalOperandPredicate();
+            switch (jsonParser.currentToken()) {
+                case VALUE_STRING:
+                    String string = jsonParser.readValueAs(String.class);
+                    value.stringValue = string;
+                    break;
+                case START_OBJECT:
+                    value.predicateValue = jsonParser.readValueAs(Predicate.class);
+                    break;
+                default: throw new IOException("Cannot deserialize LogicalOperandPredicate");
+            }
+            return value;
+        }
+    }
+
+    static class Serializer extends JsonSerializer<LogicalOperandPredicate> {
+        @Override
+        public void serialize(LogicalOperandPredicate obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+            if (obj.predicateValue != null) {
+                jsonGenerator.writeObject(obj.predicateValue);
+                return;
+            }
+            if (obj.stringValue != null) {
+                jsonGenerator.writeObject(obj.stringValue);
+                return;
+            }
+            throw new IOException("LogicalOperandPredicate must not be null");
+        }
+    }
+}
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/LogicalOperandPredicateElement.java b/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/LogicalOperandPredicateElement.java
deleted file mode 100644
index e70cb12..0000000
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/LogicalOperandPredicateElement.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package io.quicktype;
-
-import java.io.IOException;
-import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.annotation.*;
-import com.fasterxml.jackson.core.type.*;
-
-/**
- * The `filter` property must be one of the predicate definitions:
- * (1) an [expression](types.html#expression) string,
- * where `datum` can be used to refer to the current data object;
- * (2) one of the field predicates: [equal predicate](filter.html#equal-predicate);
- * [range predicate](filter.html#range-predicate), [one-of
- * predicate](filter.html#one-of-predicate);
- * (3) a [selection predicate](filter.html#selection-predicate);
- * or (4) a logical operand that combines (1), (2), or (3).
- */
-@JsonDeserialize(using = LogicalOperandPredicateElement.Deserializer.class)
-@JsonSerialize(using = LogicalOperandPredicateElement.Serializer.class)
-public class LogicalOperandPredicateElement {
-    public Predicate predicateValue;
-    public String stringValue;
-
-    static class Deserializer extends JsonDeserializer<LogicalOperandPredicateElement> {
-        @Override
-        public LogicalOperandPredicateElement deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            LogicalOperandPredicateElement value = new LogicalOperandPredicateElement();
-            switch (jsonParser.currentToken()) {
-                case VALUE_STRING:
-                    String string = jsonParser.readValueAs(String.class);
-                    value.stringValue = string;
-                    break;
-                case START_OBJECT:
-                    value.predicateValue = jsonParser.readValueAs(Predicate.class);
-                    break;
-                default: throw new IOException("Cannot deserialize LogicalOperandPredicateElement");
-            }
-            return value;
-        }
-    }
-
-    static class Serializer extends JsonSerializer<LogicalOperandPredicateElement> {
-        @Override
-        public void serialize(LogicalOperandPredicateElement obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-            if (obj.predicateValue != null) {
-                jsonGenerator.writeObject(obj.predicateValue);
-                return;
-            }
-            if (obj.stringValue != null) {
-                jsonGenerator.writeObject(obj.stringValue);
-                return;
-            }
-            throw new IOException("LogicalOperandPredicateElement must not be null");
-        }
-    }
-}
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/MarkPropDefWithCondition.java b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/MarkPropDefWithCondition.java
index c5c5748..796f64b 100644
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/MarkPropDefWithCondition.java
+++ b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/MarkPropDefWithCondition.java
@@ -48,7 +48,7 @@ import java.util.List;
  */
 public class MarkPropDefWithCondition {
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private ColorCondition condition;
     private Field field;
     private Legend legend;
@@ -56,7 +56,7 @@ public class MarkPropDefWithCondition {
     private SortUnion sort;
     private TimeUnit timeUnit;
     private Type type;
-    private ConditionalPredicateValueDefValue value;
+    private ColorValue value;
 
     /**
      * Aggregation function for the field
@@ -77,9 +77,9 @@ public class MarkPropDefWithCondition {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * One or more value definition(s) with a selection predicate.
@@ -174,7 +174,7 @@ public class MarkPropDefWithCondition {
      * A constant value in visual domain.
      */
     @JsonProperty("value")
-    public ConditionalPredicateValueDefValue getValue() { return value; }
+    public ColorValue getValue() { return value; }
     @JsonProperty("value")
-    public void setValue(ConditionalPredicateValueDefValue value) { this.value = value; }
+    public void setValue(ColorValue value) { this.value = value; }
 }
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/OneOfElement.java b/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/OneOfElement.java
deleted file mode 100644
index 7e6a5e2..0000000
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/OneOfElement.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package io.quicktype;
-
-import java.io.IOException;
-import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.annotation.*;
-import com.fasterxml.jackson.core.type.*;
-
-/**
- * The value that the field should be equal to.
- */
-@JsonDeserialize(using = OneOfElement.Deserializer.class)
-@JsonSerialize(using = OneOfElement.Serializer.class)
-public class OneOfElement {
-    public Double doubleValue;
-    public Boolean boolValue;
-    public DateTime dateTimeValue;
-    public String stringValue;
-
-    static class Deserializer extends JsonDeserializer<OneOfElement> {
-        @Override
-        public OneOfElement deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            OneOfElement value = new OneOfElement();
-            switch (jsonParser.currentToken()) {
-                case VALUE_NUMBER_INT:
-                case VALUE_NUMBER_FLOAT:
-                    value.doubleValue = jsonParser.readValueAs(Double.class);
-                    break;
-                case VALUE_TRUE:
-                case VALUE_FALSE:
-                    value.boolValue = jsonParser.readValueAs(Boolean.class);
-                    break;
-                case VALUE_STRING:
-                    String string = jsonParser.readValueAs(String.class);
-                    value.stringValue = string;
-                    break;
-                case START_OBJECT:
-                    value.dateTimeValue = jsonParser.readValueAs(DateTime.class);
-                    break;
-                default: throw new IOException("Cannot deserialize OneOfElement");
-            }
-            return value;
-        }
-    }
-
-    static class Serializer extends JsonSerializer<OneOfElement> {
-        @Override
-        public void serialize(OneOfElement obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-            if (obj.doubleValue != null) {
-                jsonGenerator.writeObject(obj.doubleValue);
-                return;
-            }
-            if (obj.boolValue != null) {
-                jsonGenerator.writeObject(obj.boolValue);
-                return;
-            }
-            if (obj.dateTimeValue != null) {
-                jsonGenerator.writeObject(obj.dateTimeValue);
-                return;
-            }
-            if (obj.stringValue != null) {
-                jsonGenerator.writeObject(obj.stringValue);
-                return;
-            }
-            throw new IOException("OneOfElement must not be null");
-        }
-    }
-}
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/OrderFieldDef.java b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/OrderFieldDef.java
index de6d278..28e11ef 100644
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/OrderFieldDef.java
+++ b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/OrderFieldDef.java
@@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.*;
 
 public class OrderFieldDef {
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private Field field;
     private SortEnum sort;
     private TimeUnit timeUnit;
@@ -29,9 +29,9 @@ public class OrderFieldDef {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * __Required.__ A string defining the name of the field from which to pull a data value
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Predicate.java b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Predicate.java
index b9c3609..be0e2df 100644
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Predicate.java
+++ b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Predicate.java
@@ -4,38 +4,38 @@ import com.fasterxml.jackson.annotation.*;
 import java.util.List;
 
 public class Predicate {
-    private ConditionalValueDefLogicalOperandPredicate not;
-    private List<LogicalOperandPredicateElement> and;
-    private List<LogicalOperandPredicateElement> or;
-    private EqualUnion equal;
+    private LogicalOperandPredicate not;
+    private List<LogicalOperandPredicate> and;
+    private List<LogicalOperandPredicate> or;
+    private Equal equal;
     private String field;
     private TimeUnit timeUnit;
     private List<RangeElement> range;
-    private List<OneOfElement> oneOf;
-    private ConditionalValueDefSelectionOperand selection;
+    private List<Equal> oneOf;
+    private SelectionOperand selection;
 
     @JsonProperty("not")
-    public ConditionalValueDefLogicalOperandPredicate getNot() { return not; }
+    public LogicalOperandPredicate getNot() { return not; }
     @JsonProperty("not")
-    public void setNot(ConditionalValueDefLogicalOperandPredicate value) { this.not = value; }
+    public void setNot(LogicalOperandPredicate value) { this.not = value; }
 
     @JsonProperty("and")
-    public List<LogicalOperandPredicateElement> getAnd() { return and; }
+    public List<LogicalOperandPredicate> getAnd() { return and; }
     @JsonProperty("and")
-    public void setAnd(List<LogicalOperandPredicateElement> value) { this.and = value; }
+    public void setAnd(List<LogicalOperandPredicate> value) { this.and = value; }
 
     @JsonProperty("or")
-    public List<LogicalOperandPredicateElement> getOr() { return or; }
+    public List<LogicalOperandPredicate> getOr() { return or; }
     @JsonProperty("or")
-    public void setOr(List<LogicalOperandPredicateElement> value) { this.or = value; }
+    public void setOr(List<LogicalOperandPredicate> value) { this.or = value; }
 
     /**
      * The value that the field should be equal to.
      */
     @JsonProperty("equal")
-    public EqualUnion getEqual() { return equal; }
+    public Equal getEqual() { return equal; }
     @JsonProperty("equal")
-    public void setEqual(EqualUnion value) { this.equal = value; }
+    public void setEqual(Equal value) { this.equal = value; }
 
     /**
      * Field to be filtered.
@@ -71,15 +71,15 @@ public class Predicate {
      * for a data item included in the filtered data.
      */
     @JsonProperty("oneOf")
-    public List<OneOfElement> getOneOf() { return oneOf; }
+    public List<Equal> getOneOf() { return oneOf; }
     @JsonProperty("oneOf")
-    public void setOneOf(List<OneOfElement> value) { this.oneOf = value; }
+    public void setOneOf(List<Equal> value) { this.oneOf = value; }
 
     /**
      * Filter using a selection name.
      */
     @JsonProperty("selection")
-    public ConditionalValueDefSelectionOperand getSelection() { return selection; }
+    public SelectionOperand getSelection() { return selection; }
     @JsonProperty("selection")
-    public void setSelection(ConditionalValueDefSelectionOperand value) { this.selection = value; }
+    public void setSelection(SelectionOperand value) { this.selection = value; }
 }
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Selection.java b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Selection.java
index 16251b4..0520466 100644
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Selection.java
+++ b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Selection.java
@@ -4,22 +4,22 @@ import com.fasterxml.jackson.annotation.*;
 import java.util.List;
 
 public class Selection {
-    private ConditionalValueDefSelectionOperand not;
-    private List<SelectionOperandElement> and;
-    private List<SelectionOperandElement> or;
+    private SelectionOperand not;
+    private List<SelectionOperand> and;
+    private List<SelectionOperand> or;
 
     @JsonProperty("not")
-    public ConditionalValueDefSelectionOperand getNot() { return not; }
+    public SelectionOperand getNot() { return not; }
     @JsonProperty("not")
-    public void setNot(ConditionalValueDefSelectionOperand value) { this.not = value; }
+    public void setNot(SelectionOperand value) { this.not = value; }
 
     @JsonProperty("and")
-    public List<SelectionOperandElement> getAnd() { return and; }
+    public List<SelectionOperand> getAnd() { return and; }
     @JsonProperty("and")
-    public void setAnd(List<SelectionOperandElement> value) { this.and = value; }
+    public void setAnd(List<SelectionOperand> value) { this.and = value; }
 
     @JsonProperty("or")
-    public List<SelectionOperandElement> getOr() { return or; }
+    public List<SelectionOperand> getOr() { return or; }
     @JsonProperty("or")
-    public void setOr(List<SelectionOperandElement> value) { this.or = value; }
+    public void setOr(List<SelectionOperand> value) { this.or = value; }
 }
diff --git a/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/SelectionOperand.java b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/SelectionOperand.java
new file mode 100644
index 0000000..7aa449b
--- /dev/null
+++ b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/SelectionOperand.java
@@ -0,0 +1,54 @@
+package io.quicktype;
+
+import java.io.IOException;
+import java.io.IOException;
+import com.fasterxml.jackson.core.*;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.annotation.*;
+import com.fasterxml.jackson.core.type.*;
+
+/**
+ * Filter using a selection name.
+ *
+ * A [selection name](selection.html), or a series of [composed
+ * selections](selection.html#compose).
+ */
+@JsonDeserialize(using = SelectionOperand.Deserializer.class)
+@JsonSerialize(using = SelectionOperand.Serializer.class)
+public class SelectionOperand {
+    public Selection selectionValue;
+    public String stringValue;
+
+    static class Deserializer extends JsonDeserializer<SelectionOperand> {
+        @Override
+        public SelectionOperand deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            SelectionOperand value = new SelectionOperand();
+            switch (jsonParser.currentToken()) {
+                case VALUE_STRING:
+                    String string = jsonParser.readValueAs(String.class);
+                    value.stringValue = string;
+                    break;
+                case START_OBJECT:
+                    value.selectionValue = jsonParser.readValueAs(Selection.class);
+                    break;
+                default: throw new IOException("Cannot deserialize SelectionOperand");
+            }
+            return value;
+        }
+    }
+
+    static class Serializer extends JsonSerializer<SelectionOperand> {
+        @Override
+        public void serialize(SelectionOperand obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+            if (obj.selectionValue != null) {
+                jsonGenerator.writeObject(obj.selectionValue);
+                return;
+            }
+            if (obj.stringValue != null) {
+                jsonGenerator.writeObject(obj.stringValue);
+                return;
+            }
+            throw new IOException("SelectionOperand must not be null");
+        }
+    }
+}
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/SelectionOperandElement.java b/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/SelectionOperandElement.java
deleted file mode 100644
index 269da8d..0000000
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/SelectionOperandElement.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package io.quicktype;
-
-import java.io.IOException;
-import java.io.IOException;
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.databind.*;
-import com.fasterxml.jackson.databind.annotation.*;
-import com.fasterxml.jackson.core.type.*;
-
-/**
- * Filter using a selection name.
- *
- * A [selection name](selection.html), or a series of [composed
- * selections](selection.html#compose).
- */
-@JsonDeserialize(using = SelectionOperandElement.Deserializer.class)
-@JsonSerialize(using = SelectionOperandElement.Serializer.class)
-public class SelectionOperandElement {
-    public Selection selectionValue;
-    public String stringValue;
-
-    static class Deserializer extends JsonDeserializer<SelectionOperandElement> {
-        @Override
-        public SelectionOperandElement deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
-            SelectionOperandElement value = new SelectionOperandElement();
-            switch (jsonParser.currentToken()) {
-                case VALUE_STRING:
-                    String string = jsonParser.readValueAs(String.class);
-                    value.stringValue = string;
-                    break;
-                case START_OBJECT:
-                    value.selectionValue = jsonParser.readValueAs(Selection.class);
-                    break;
-                default: throw new IOException("Cannot deserialize SelectionOperandElement");
-            }
-            return value;
-        }
-    }
-
-    static class Serializer extends JsonSerializer<SelectionOperandElement> {
-        @Override
-        public void serialize(SelectionOperandElement obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
-            if (obj.selectionValue != null) {
-                jsonGenerator.writeObject(obj.selectionValue);
-                return;
-            }
-            if (obj.stringValue != null) {
-                jsonGenerator.writeObject(obj.stringValue);
-                return;
-            }
-            throw new IOException("SelectionOperandElement must not be null");
-        }
-    }
-}
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/TextDefWithCondition.java b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/TextDefWithCondition.java
index bab354b..5bc625d 100644
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/TextDefWithCondition.java
+++ b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/TextDefWithCondition.java
@@ -23,13 +23,13 @@ import java.util.List;
  */
 public class TextDefWithCondition {
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private TextCondition condition;
     private Field field;
     private String format;
     private TimeUnit timeUnit;
     private Type type;
-    private ConditionalPredicateValueDefValue value;
+    private ColorValue value;
 
     /**
      * Aggregation function for the field
@@ -50,9 +50,9 @@ public class TextDefWithCondition {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * One or more value definition(s) with a selection predicate.
@@ -120,7 +120,7 @@ public class TextDefWithCondition {
      * A constant value in visual domain.
      */
     @JsonProperty("value")
-    public ConditionalPredicateValueDefValue getValue() { return value; }
+    public ColorValue getValue() { return value; }
     @JsonProperty("value")
-    public void setValue(ConditionalPredicateValueDefValue value) { this.value = value; }
+    public void setValue(ColorValue value) { this.value = value; }
 }
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Transform.java b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Transform.java
index cbf0ea3..1065f00 100644
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Transform.java
+++ b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Transform.java
@@ -4,13 +4,13 @@ import com.fasterxml.jackson.annotation.*;
 import java.util.List;
 
 public class Transform {
-    private ConditionalValueDefLogicalOperandPredicate filter;
+    private LogicalOperandPredicate filter;
     private Style as;
     private String calculate;
     private String transformDefault;
     private LookupData from;
     private String lookup;
-    private Bin bin;
+    private TransformBin bin;
     private String field;
     private TimeUnit timeUnit;
     private List<AggregatedFieldDef> aggregate;
@@ -27,9 +27,9 @@ public class Transform {
      * or (4) a logical operand that combines (1), (2), or (3).
      */
     @JsonProperty("filter")
-    public ConditionalValueDefLogicalOperandPredicate getFilter() { return filter; }
+    public LogicalOperandPredicate getFilter() { return filter; }
     @JsonProperty("filter")
-    public void setFilter(ConditionalValueDefLogicalOperandPredicate value) { this.filter = value; }
+    public void setFilter(LogicalOperandPredicate value) { this.filter = value; }
 
     /**
      * The field for storing the computed formula value.
@@ -87,9 +87,9 @@ public class Transform {
      * An object indicating bin properties, or simply `true` for using default bin parameters.
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public TransformBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(TransformBin value) { this.bin = value; }
 
     /**
      * The data field to bin.
diff --git a/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/TransformBin.java b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/TransformBin.java
new file mode 100644
index 0000000..ae29fc2
--- /dev/null
+++ b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/TransformBin.java
@@ -0,0 +1,48 @@
+package io.quicktype;
+
+import java.io.IOException;
+import java.io.IOException;
+import com.fasterxml.jackson.core.*;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.databind.annotation.*;
+import com.fasterxml.jackson.core.type.*;
+
+@JsonDeserialize(using = TransformBin.Deserializer.class)
+@JsonSerialize(using = TransformBin.Serializer.class)
+public class TransformBin {
+    public Boolean boolValue;
+    public BinParams binParamsValue;
+
+    static class Deserializer extends JsonDeserializer<TransformBin> {
+        @Override
+        public TransformBin deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
+            TransformBin value = new TransformBin();
+            switch (jsonParser.currentToken()) {
+                case VALUE_TRUE:
+                case VALUE_FALSE:
+                    value.boolValue = jsonParser.readValueAs(Boolean.class);
+                    break;
+                case START_OBJECT:
+                    value.binParamsValue = jsonParser.readValueAs(BinParams.class);
+                    break;
+                default: throw new IOException("Cannot deserialize TransformBin");
+            }
+            return value;
+        }
+    }
+
+    static class Serializer extends JsonSerializer<TransformBin> {
+        @Override
+        public void serialize(TransformBin obj, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+            if (obj.boolValue != null) {
+                jsonGenerator.writeObject(obj.boolValue);
+                return;
+            }
+            if (obj.binParamsValue != null) {
+                jsonGenerator.writeObject(obj.binParamsValue);
+                return;
+            }
+            throw new IOException("TransformBin must not be null");
+        }
+    }
+}
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Values.java b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Values.java
index dc130c0..486b136 100644
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Values.java
+++ b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/Values.java
@@ -27,8 +27,6 @@ public class Values {
         public Values deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
             Values value = new Values();
             switch (jsonParser.currentToken()) {
-                case VALUE_NULL:
-                    break;
                 case VALUE_STRING:
                     String string = jsonParser.readValueAs(String.class);
                     value.stringValue = string;
@@ -60,7 +58,7 @@ public class Values {
                 jsonGenerator.writeObject(obj.stringValue);
                 return;
             }
-            jsonGenerator.writeNull();
+            throw new IOException("Values must not be null");
         }
     }
 }
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/X2Class.java b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/X2Class.java
index 4742838..38d62b5 100644
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/X2Class.java
+++ b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/X2Class.java
@@ -13,11 +13,11 @@ import com.fasterxml.jackson.annotation.*;
  */
 public class X2Class {
     private AggregateOp aggregate;
-    private Bin bin;
+    private ColorBin bin;
     private Field field;
     private TimeUnit timeUnit;
     private Type type;
-    private ConditionalPredicateValueDefValue value;
+    private ConditionalValueDefValue value;
 
     /**
      * Aggregation function for the field
@@ -38,9 +38,9 @@ public class X2Class {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * __Required.__ A string defining the name of the field from which to pull a data value
@@ -86,7 +86,7 @@ public class X2Class {
      * `0` to `1` for opacity).
      */
     @JsonProperty("value")
-    public ConditionalPredicateValueDefValue getValue() { return value; }
+    public ConditionalValueDefValue getValue() { return value; }
     @JsonProperty("value")
-    public void setValue(ConditionalPredicateValueDefValue value) { this.value = value; }
+    public void setValue(ConditionalValueDefValue value) { this.value = value; }
 }
diff --git a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/XClass.java b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/XClass.java
index 38c4a64..c71f712 100644
--- a/base/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/XClass.java
+++ b/head/schema-java-lombok/test/inputs/schema/vega-lite.schema/default/src/main/java/io/quicktype/XClass.java
@@ -12,14 +12,14 @@ import com.fasterxml.jackson.annotation.*;
 public class XClass {
     private AggregateOp aggregate;
     private Axis axis;
-    private Bin bin;
+    private ColorBin bin;
     private Field field;
     private Scale scale;
     private SortUnion sort;
     private StackOffset stack;
     private TimeUnit timeUnit;
     private Type type;
-    private ConditionalPredicateValueDefValue value;
+    private ConditionalValueDefValue value;
 
     /**
      * Aggregation function for the field
@@ -51,9 +51,9 @@ public class XClass {
      * __Default value:__ `false`
      */
     @JsonProperty("bin")
-    public Bin getBin() { return bin; }
+    public ColorBin getBin() { return bin; }
     @JsonProperty("bin")
-    public void setBin(Bin value) { this.bin = value; }
+    public void setBin(ColorBin value) { this.bin = value; }
 
     /**
      * __Required.__ A string defining the name of the field from which to pull a data value
@@ -151,7 +151,7 @@ public class XClass {
      * `0` to `1` for opacity).
      */
     @JsonProperty("value")
-    public ConditionalPredicateValueDefValue getValue() { return value; }
+    public ConditionalValueDefValue getValue() { return value; }
     @JsonProperty("value")
-    public void setValue(ConditionalPredicateValueDefValue value) { this.value = value; }
+    public void setValue(ConditionalValueDefValue value) { this.value = value; }
 }
diff --git a/head/schema-javascript/test/inputs/schema/required-in-any-of.schema/default/TopLevel.js b/head/schema-javascript/test/inputs/schema/required-in-any-of.schema/default/TopLevel.js
new file mode 100644
index 0000000..c2a4c95
--- /dev/null
+++ b/head/schema-javascript/test/inputs/schema/required-in-any-of.schema/default/TopLevel.js
@@ -0,0 +1,186 @@
+// To parse this data:
+//
+//   const Convert = require("./TopLevel");
+//
+//   const topLevel = Convert.toTopLevel(json);
+//
+// These functions will throw an error if the JSON doesn't
+// match the expected interface, even if the JSON is valid.
+
+// Converts JSON strings to/from your types
+// and asserts the results of JSON.parse at runtime
+function toTopLevel(json) {
+    return cast(JSON.parse(json), r("TopLevel"));
+}
+
+function topLevelToJson(value) {
+    return JSON.stringify(uncast(value, r("TopLevel")), null, 2);
+}
+
+function invalidValue(typ, val, key, parent = '') {
+    const prettyTyp = prettyTypeName(typ);
+    const parentText = parent ? ` on ${parent}` : '';
+    const keyText = key ? ` for key "${key}"` : '';
+    throw Error(`Invalid value${keyText}${parentText}. Expected ${prettyTyp} but got ${JSON.stringify(val)}`);
+}
+
+function prettyTypeName(typ) {
+    if (Array.isArray(typ)) {
+        if (typ.length === 2 && typ[0] === undefined) {
+            return `an optional ${prettyTypeName(typ[1])}`;
+        } else {
+            return `one of [${typ.map(a => { return prettyTypeName(a); }).join(", ")}]`;
+        }
+    } else if (typeof typ === "object" && typ.literal !== undefined) {
+        return typ.literal;
+    } else {
+        return typeof typ;
+    }
+}
+
+function jsonToJSProps(typ) {
+    if (typ.jsonToJS === undefined) {
+        const map = {};
+        typ.props.forEach((p) => map[p.json] = { key: p.js, typ: p.typ });
+        typ.jsonToJS = map;
+    }
+    return typ.jsonToJS;
+}
+
+function jsToJSONProps(typ) {
+    if (typ.jsToJSON === undefined) {
+        const map = {};
+        typ.props.forEach((p) => map[p.js] = { key: p.json, typ: p.typ });
+        typ.jsToJSON = map;
+    }
+    return typ.jsToJSON;
+}
+
+function transform(val, typ, getProps, key = '', parent = '') {
+    function transformPrimitive(typ, val) {
+        if (typeof typ === typeof val) return val;
+        return invalidValue(typ, val, key, parent);
+    }
+
+    function transformUnion(typs, val) {
+        // val must validate against one typ in typs
+        const l = typs.length;
+        for (let i = 0; i < l; i++) {
+            const typ = typs[i];
+            try {
+                return transform(val, typ, getProps);
+            } catch (_) {}
+        }
+        return invalidValue(typs, val, key, parent);
+    }
+
+    function transformEnum(cases, val) {
+        if (cases.indexOf(val) !== -1) return val;
+        return invalidValue(cases.map(a => { return l(a); }), val, key, parent);
+    }
+
+    function transformArray(typ, val) {
+        // val must be an array with no invalid elements
+        if (!Array.isArray(val)) return invalidValue(l("array"), val, key, parent);
+        return val.map(el => transform(el, typ, getProps));
+    }
+
+    function transformDate(val) {
+        if (val === null) {
+            return null;
+        }
+        const d = new Date(val);
+        if (isNaN(d.valueOf())) {
+            return invalidValue(l("Date"), val, key, parent);
+        }
+        return d;
+    }
+
+    function transformObject(props, additional, val) {
+        if (val === null || typeof val !== "object" || Array.isArray(val)) {
+            return invalidValue(l(ref || "object"), val, key, parent);
+        }
+        const result = {};
+        Object.getOwnPropertyNames(props).forEach(key => {
+            const prop = props[key];
+            const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined;
+            result[prop.key] = transform(v, prop.typ, getProps, key, ref);
+        });
+        Object.getOwnPropertyNames(val).forEach(key => {
+            if (!Object.prototype.hasOwnProperty.call(props, key)) {
+                result[key] = transform(val[key], additional, getProps, key, ref);
+            }
+        });
+        return result;
+    }
+
+    if (typ === "any") return val;
+    if (typ === null) {
+        if (val === null) return val;
+        return invalidValue(typ, val, key, parent);
+    }
+    if (typ === false) return invalidValue(typ, val, key, parent);
+    let ref = undefined;
+    while (typeof typ === "object" && typ.ref !== undefined) {
+        ref = typ.ref;
+        typ = typeMap[typ.ref];
+    }
+    if (Array.isArray(typ)) return transformEnum(typ, val);
+    if (typeof typ === "object") {
+        return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val)
+            : typ.hasOwnProperty("arrayItems")    ? transformArray(typ.arrayItems, val)
+            : typ.hasOwnProperty("props")         ? transformObject(getProps(typ), typ.additional, val)
+            : invalidValue(typ, val, key, parent);
+    }
+    // Numbers can be parsed by Date but shouldn't be.
+    if (typ === Date && typeof val !== "number") return transformDate(val);
+    return transformPrimitive(typ, val);
+}
+
+function cast(val, typ) {
+    return transform(val, typ, jsonToJSProps);
+}
+
+function uncast(val, typ) {
+    return transform(val, typ, jsToJSONProps);
+}
+
+function l(typ) {
+    return { literal: typ };
+}
+
+function a(typ) {
+    return { arrayItems: typ };
+}
+
+function u(...typs) {
+    return { unionMembers: typs };
+}
+
+function o(props, additional) {
+    return { props, additional };
+}
+
+function m(additional) {
+    const props = [];
+    return { props, additional };
+}
+
+function r(name) {
+    return { ref: name };
+}
+
+const typeMap = {
+    "TopLevel": o([
+        { json: "anyof", js: "anyof", typ: r("Anyof") },
+    ], false),
+    "Anyof": o([
+        { json: "name", js: "name", typ: "" },
+        { json: "size", js: "size", typ: u(undefined, "") },
+    ], false),
+};
+
+module.exports = {
+    "topLevelToJson": topLevelToJson,
+    "toTopLevel": toTopLevel,
+};
diff --git a/base/schema-javascript/test/inputs/schema/vega-lite.schema/default/TopLevel.js b/head/schema-javascript/test/inputs/schema/vega-lite.schema/default/TopLevel.js
index 06dcc21..1c7bd72 100644
--- a/base/schema-javascript/test/inputs/schema/vega-lite.schema/default/TopLevel.js
+++ b/head/schema-javascript/test/inputs/schema/vega-lite.schema/default/TopLevel.js
@@ -178,9 +178,9 @@ const typeMap = {
         { json: "config", js: "config", typ: u(undefined, r("Config")) },
         { json: "data", js: "data", typ: u(undefined, r("Data")) },
         { json: "description", js: "description", typ: u(undefined, "") },
-        { json: "encoding", js: "encoding", typ: u(undefined, r("EncodingWithFacet")) },
+        { json: "encoding", js: "encoding", typ: r("EncodingWithFacet") },
         { json: "height", js: "height", typ: u(undefined, 3.14) },
-        { json: "mark", js: "mark", typ: u(undefined, u(r("MarkDef"), r("Mark"))) },
+        { json: "mark", js: "mark", typ: u(r("MarkDef"), r("Mark")) },
         { json: "name", js: "name", typ: u(undefined, "") },
         { json: "padding", js: "padding", typ: u(undefined, u(r("PaddingClass"), 3.14)) },
         { json: "projection", js: "projection", typ: u(undefined, r("Projection")) },
@@ -188,13 +188,13 @@ const typeMap = {
         { json: "title", js: "title", typ: u(undefined, u(r("TitleParams"), "")) },
         { json: "transform", js: "transform", typ: u(undefined, a(r("Transform"))) },
         { json: "width", js: "width", typ: u(undefined, 3.14) },
-        { json: "layer", js: "layer", typ: u(undefined, a(r("LayerSpec"))) },
+        { json: "layer", js: "layer", typ: a(r("LayerSpec")) },
         { json: "resolve", js: "resolve", typ: u(undefined, r("Resolve")) },
-        { json: "facet", js: "facet", typ: u(undefined, r("FacetMapping")) },
-        { json: "spec", js: "spec", typ: u(undefined, r("Spec")) },
-        { json: "repeat", js: "repeat", typ: u(undefined, r("Repeat")) },
-        { json: "vconcat", js: "vconcat", typ: u(undefined, a(r("Spec"))) },
-        { json: "hconcat", js: "hconcat", typ: u(undefined, a(r("Spec"))) },
+        { json: "facet", js: "facet", typ: r("FacetMapping") },
+        { json: "spec", js: "spec", typ: r("Spec") },
+        { json: "repeat", js: "repeat", typ: r("Repeat") },
+        { json: "vconcat", js: "vconcat", typ: a(r("Spec")) },
+        { json: "hconcat", js: "hconcat", typ: a(r("Spec")) },
     ], false),
     "AutoSizeParams": o([
         { json: "contains", js: "contains", typ: u(undefined, r("Contains")) },
@@ -468,8 +468,8 @@ const typeMap = {
     "RangeConfigValueVGScheme": o([
         { json: "count", js: "count", typ: u(undefined, 3.14) },
         { json: "extent", js: "extent", typ: u(undefined, a(3.14)) },
-        { json: "scheme", js: "scheme", typ: u(undefined, "") },
-        { json: "step", js: "step", typ: u(undefined, 3.14) },
+        { json: "scheme", js: "scheme", typ: "" },
+        { json: "step", js: "step", typ: 3.14 },
     ], false),
     "ScaleConfig": o([
         { json: "bandPaddingInner", js: "bandPaddingInner", typ: u(undefined, 3.14) },
@@ -538,7 +538,7 @@ const typeMap = {
     "VGBinding": o([
         { json: "element", js: "element", typ: u(undefined, "") },
         { json: "input", js: "input", typ: "" },
-        { json: "options", js: "options", typ: u(undefined, a("")) },
+        { json: "options", js: "options", typ: a("") },
         { json: "max", js: "max", typ: u(undefined, 3.14) },
         { json: "min", js: "min", typ: u(undefined, 3.14) },
         { json: "step", js: "step", typ: u(undefined, 3.14) },
@@ -666,9 +666,9 @@ const typeMap = {
     ], false),
     "Data": o([
         { json: "format", js: "format", typ: u(undefined, r("DataFormat")) },
-        { json: "url", js: "url", typ: u(undefined, "") },
-        { json: "values", js: "values", typ: u(undefined, u(a(u(true, 3.14, m("any"), "")), m("any"), "")) },
-        { json: "name", js: "name", typ: u(undefined, "") },
+        { json: "url", js: "url", typ: "" },
+        { json: "values", js: "values", typ: u(a(u(true, 3.14, m("any"), "")), m("any"), "") },
+        { json: "name", js: "name", typ: "" },
     ], false),
     "DataFormat": o([
         { json: "parse", js: "parse", typ: u(undefined, u(r("ParseEnum"), m("any"))) },
@@ -703,7 +703,7 @@ const typeMap = {
         { json: "scale", js: "scale", typ: u(undefined, r("Scale")) },
         { json: "sort", js: "sort", typ: u(undefined, u(r("SortField"), r("SortEnum"), null)) },
         { json: "timeUnit", js: "timeUnit", typ: u(undefined, r("TimeUnit")) },
-        { json: "type", js: "type", typ: u(undefined, r("Type")) },
+        { json: "type", js: "type", typ: r("Type") },
         { json: "value", js: "value", typ: u(undefined, u(true, 3.14, "")) },
     ], false),
     "BinParams": o([
@@ -717,25 +717,25 @@ const typeMap = {
         { json: "steps", js: "steps", typ: u(undefined, a(3.14)) },
     ], false),
     "ConditionalValueDef": o([
-        { json: "test", js: "test", typ: u(undefined, u(r("Predicate"), "")) },
+        { json: "test", js: "test", typ: u(r("Predicate"), "") },
         { json: "value", js: "value", typ: u(true, 3.14, "") },
-        { json: "selection", js: "selection", typ: u(undefined, u(r("Selection"), "")) },
+        { json: "selection", js: "selection", typ: u(r("Selection"), "") },
     ], false),
     "Selection": o([
-        { json: "not", js: "not", typ: u(undefined, u(r("Selection"), "")) },
-        { json: "and", js: "and", typ: u(undefined, a(u(r("Selection"), ""))) },
-        { json: "or", js: "or", typ: u(undefined, a(u(r("Selection"), ""))) },
+        { json: "not", js: "not", typ: u(r("Selection"), "") },
+        { json: "and", js: "and", typ: a(u(r("Selection"), "")) },
+        { json: "or", js: "or", typ: a(u(r("Selection"), "")) },
     ], false),
     "Predicate": o([
-        { json: "not", js: "not", typ: u(undefined, u(r("Predicate"), "")) },
-        { json: "and", js: "and", typ: u(undefined, a(u(r("Predicate"), ""))) },
-        { json: "or", js: "or", typ: u(undefined, a(u(r("Predicate"), ""))) },
-        { json: "equal", js: "equal", typ: u(undefined, u(true, r("DateTime"), 3.14, "")) },
-        { json: "field", js: "field", typ: u(undefined, "") },
+        { json: "not", js: "not", typ: u(r("Predicate"), "") },
+        { json: "and", js: "and", typ: a(u(r("Predicate"), "")) },
+        { json: "or", js: "or", typ: a(u(r("Predicate"), "")) },
+        { json: "equal", js: "equal", typ: u(true, r("DateTime"), 3.14, "") },
+        { json: "field", js: "field", typ: "" },
         { json: "timeUnit", js: "timeUnit", typ: u(undefined, r("TimeUnit")) },
-        { json: "range", js: "range", typ: u(undefined, a(u(r("DateTime"), 3.14, null))) },
-        { json: "oneOf", js: "oneOf", typ: u(undefined, a(u(true, r("DateTime"), 3.14, ""))) },
-        { json: "selection", js: "selection", typ: u(undefined, u(r("Selection"), "")) },
+        { json: "range", js: "range", typ: a(u(r("DateTime"), 3.14, null)) },
+        { json: "oneOf", js: "oneOf", typ: a(u(true, r("DateTime"), 3.14, "")) },
+        { json: "selection", js: "selection", typ: u(r("Selection"), "") },
     ], false),
     "DateTime": o([
         { json: "date", js: "date", typ: u(undefined, 3.14) },
@@ -750,9 +750,9 @@ const typeMap = {
         { json: "year", js: "year", typ: u(undefined, 3.14) },
     ], false),
     "ConditionalPredicateMarkPropFieldDefClass": o([
-        { json: "test", js: "test", typ: u(undefined, u(r("Predicate"), "")) },
-        { json: "value", js: "value", typ: u(undefined, u(true, 3.14, "")) },
-        { json: "selection", js: "selection", typ: u(undefined, u(r("Selection"), "")) },
+        { json: "test", js: "test", typ: u(r("Predicate"), "") },
+        { json: "value", js: "value", typ: u(true, 3.14, "") },
+        { json: "selection", js: "selection", typ: u(r("Selection"), "") },
         { json: "aggregate", js: "aggregate", typ: u(undefined, r("AggregateOp")) },
         { json: "bin", js: "bin", typ: u(undefined, u(true, r("BinParams"))) },
         { json: "field", js: "field", typ: u(undefined, u(r("RepeatRef"), "")) },
@@ -760,7 +760,7 @@ const typeMap = {
         { json: "scale", js: "scale", typ: u(undefined, r("Scale")) },
         { json: "sort", js: "sort", typ: u(undefined, u(r("SortField"), r("SortEnum"), null)) },
         { json: "timeUnit", js: "timeUnit", typ: u(undefined, r("TimeUnit")) },
-        { json: "type", js: "type", typ: u(undefined, r("Type")) },
+        { json: "type", js: "type", typ: r("Type") },
     ], false),
     "RepeatRef": o([
         { json: "repeat", js: "repeat", typ: r("RepeatEnum") },
@@ -843,18 +843,18 @@ const typeMap = {
         { json: "condition", js: "condition", typ: u(undefined, u(a(r("ConditionalValueDef")), r("ConditionalPredicateFieldDefClass"))) },
         { json: "field", js: "field", typ: u(undefined, u(r("RepeatRef"), "")) },
         { json: "timeUnit", js: "timeUnit", typ: u(undefined, r("TimeUnit")) },
-        { json: "type", js: "type", typ: u(undefined, r("Type")) },
+        { json: "type", js: "type", typ: r("Type") },
         { json: "value", js: "value", typ: u(undefined, u(true, 3.14, "")) },
     ], false),
     "ConditionalPredicateFieldDefClass": o([
-        { json: "test", js: "test", typ: u(undefined, u(r("Predicate"), "")) },
-        { json: "value", js: "value", typ: u(undefined, u(true, 3.14, "")) },
-        { json: "selection", js: "selection", typ: u(undefined, u(r("Selection"), "")) },
+        { json: "test", js: "test", typ: u(r("Predicate"), "") },
+        { json: "value", js: "value", typ: u(true, 3.14, "") },
+        { json: "selection", js: "selection", typ: u(r("Selection"), "") },
         { json: "aggregate", js: "aggregate", typ: u(undefined, r("AggregateOp")) },
         { json: "bin", js: "bin", typ: u(undefined, u(true, r("BinParams"))) },
         { json: "field", js: "field", typ: u(undefined, u(r("RepeatRef"), "")) },
         { json: "timeUnit", js: "timeUnit", typ: u(undefined, r("TimeUnit")) },
-        { json: "type", js: "type", typ: u(undefined, r("Type")) },
+        { json: "type", js: "type", typ: r("Type") },
     ], false),
     "OrderFieldDef": o([
         { json: "aggregate", js: "aggregate", typ: u(undefined, r("AggregateOp")) },
@@ -871,19 +871,19 @@ const typeMap = {
         { json: "field", js: "field", typ: u(undefined, u(r("RepeatRef"), "")) },
         { json: "format", js: "format", typ: u(undefined, "") },
         { json: "timeUnit", js: "timeUnit", typ: u(undefined, r("TimeUnit")) },
-        { json: "type", js: "type", typ: u(undefined, r("Type")) },
+        { json: "type", js: "type", typ: r("Type") },
         { json: "value", js: "value", typ: u(undefined, u(true, 3.14, "")) },
     ], false),
     "ConditionalPredicateTextFieldDefClass": o([
-        { json: "test", js: "test", typ: u(undefined, u(r("Predicate"), "")) },
-        { json: "value", js: "value", typ: u(undefined, u(true, 3.14, "")) },
-        { json: "selection", js: "selection", typ: u(undefined, u(r("Selection"), "")) },
+        { json: "test", js: "test", typ: u(r("Predicate"), "") },
+        { json: "value", js: "value", typ: u(true, 3.14, "") },
+        { json: "selection", js: "selection", typ: u(r("Selection"), "") },
         { json: "aggregate", js: "aggregate", typ: u(undefined, r("AggregateOp")) },
         { json: "bin", js: "bin", typ: u(undefined, u(true, r("BinParams"))) },
         { json: "field", js: "field", typ: u(undefined, u(r("RepeatRef"), "")) },
         { json: "format", js: "format", typ: u(undefined, "") },
         { json: "timeUnit", js: "timeUnit", typ: u(undefined, r("TimeUnit")) },
-        { json: "type", js: "type", typ: u(undefined, r("Type")) },
+        { json: "type", js: "type", typ: r("Type") },
     ], false),
     "XClass": o([
         { json: "aggregate", js: "aggregate", typ: u(undefined, r("AggregateOp")) },
@@ -894,8 +894,8 @@ const typeMap = {
         { json: "sort", js: "sort", typ: u(undefined, u(r("SortField"), r("SortEnum"), null)) },
         { json: "stack", js: "stack", typ: u(undefined, u(r("StackOffset"), null)) },
         { json: "timeUnit", js: "timeUnit", typ: u(undefined, r("TimeUnit")) },
-        { json: "type", js: "type", typ: u(undefined, r("Type")) },
-        { json: "value", js: "value", typ: u(undefined, u(true, 3.14, "")) },
+        { json: "type", js: "type", typ: r("Type") },
+        { json: "value", js: "value", typ: u(true, 3.14, "") },
     ], false),
     "Axis": o([
         { json: "domain", js: "domain", typ: u(undefined, true) },
@@ -926,8 +926,8 @@ const typeMap = {
         { json: "bin", js: "bin", typ: u(undefined, u(true, r("BinParams"))) },
         { json: "field", js: "field", typ: u(undefined, u(r("RepeatRef"), "")) },
         { json: "timeUnit", js: "timeUnit", typ: u(undefined, r("TimeUnit")) },
-        { json: "type", js: "type", typ: u(undefined, r("Type")) },
-        { json: "value", js: "value", typ: u(undefined, u(true, 3.14, "")) },
+        { json: "type", js: "type", typ: r("Type") },
+        { json: "value", js: "value", typ: u(true, 3.14, "") },
     ], false),
     "FacetMapping": o([
         { json: "column", js: "column", typ: u(undefined, r("FacetFieldDef")) },
@@ -937,21 +937,21 @@ const typeMap = {
         { json: "data", js: "data", typ: u(undefined, r("Data")) },
         { json: "description", js: "description", typ: u(undefined, "") },
         { json: "height", js: "height", typ: u(undefined, 3.14) },
-        { json: "layer", js: "layer", typ: u(undefined, a(r("LayerSpec"))) },
+        { json: "layer", js: "layer", typ: a(r("LayerSpec")) },
         { json: "name", js: "name", typ: u(undefined, "") },
         { json: "resolve", js: "resolve", typ: u(undefined, r("Resolve")) },
         { json: "title", js: "title", typ: u(undefined, u(r("TitleParams"), "")) },
         { json: "transform", js: "transform", typ: u(undefined, a(r("Transform"))) },
         { json: "width", js: "width", typ: u(undefined, 3.14) },
-        { json: "encoding", js: "encoding", typ: u(undefined, r("Encoding")) },
-        { json: "mark", js: "mark", typ: u(undefined, u(r("MarkDef"), r("Mark"))) },
+        { json: "encoding", js: "encoding", typ: r("Encoding") },
+        { json: "mark", js: "mark", typ: u(r("MarkDef"), r("Mark")) },
         { json: "projection", js: "projection", typ: u(undefined, r("Projection")) },
         { json: "selection", js: "selection", typ: u(undefined, m(r("SelectionDef"))) },
-        { json: "facet", js: "facet", typ: u(undefined, r("FacetMapping")) },
-        { json: "spec", js: "spec", typ: u(undefined, r("Spec")) },
-        { json: "repeat", js: "repeat", typ: u(undefined, r("Repeat")) },
-        { json: "vconcat", js: "vconcat", typ: u(undefined, a(r("Spec"))) },
-        { json: "hconcat", js: "hconcat", typ: u(undefined, a(r("Spec"))) },
+        { json: "facet", js: "facet", typ: r("FacetMapping") },
+        { json: "spec", js: "spec", typ: r("Spec") },
+        { json: "repeat", js: "repeat", typ: r("Repeat") },
+        { json: "vconcat", js: "vconcat", typ: a(r("Spec")) },
+        { json: "hconcat", js: "hconcat", typ: a(r("Spec")) },
     ], false),
     "Encoding": o([
         { json: "color", js: "color", typ: u(undefined, r("MarkPropDefWithCondition")) },
@@ -972,14 +972,14 @@ const typeMap = {
         { json: "data", js: "data", typ: u(undefined, r("Data")) },
         { json: "description", js: "description", typ: u(undefined, "") },
         { json: "height", js: "height", typ: u(undefined, 3.14) },
-        { json: "layer", js: "layer", typ: u(undefined, a(r("LayerSpec"))) },
+        { json: "layer", js: "layer", typ: a(r("LayerSpec")) },
         { json: "name", js: "name", typ: u(undefined, "") },
         { json: "resolve", js: "resolve", typ: u(undefined, r("Resolve")) },
         { json: "title", js: "title", typ: u(undefined, u(r("TitleParams"), "")) },
         { json: "transform", js: "transform", typ: u(undefined, a(r("Transform"))) },
         { json: "width", js: "width", typ: u(undefined, 3.14) },
-        { json: "encoding", js: "encoding", typ: u(undefined, r("Encoding")) },
-        { json: "mark", js: "mark", typ: u(undefined, u(r("MarkDef"), r("Mark"))) },
+        { json: "encoding", js: "encoding", typ: r("Encoding") },
+        { json: "mark", js: "mark", typ: u(r("MarkDef"), r("Mark")) },
         { json: "projection", js: "projection", typ: u(undefined, r("Projection")) },
         { json: "selection", js: "selection", typ: u(undefined, m(r("SelectionDef"))) },
     ], false),
@@ -1083,16 +1083,16 @@ const typeMap = {
         { json: "text", js: "text", typ: "" },
     ], false),
     "Transform": o([
-        { json: "filter", js: "filter", typ: u(undefined, u(r("Predicate"), "")) },
+        { json: "filter", js: "filter", typ: u(r("Predicate"), "") },
         { json: "as", js: "as", typ: u(undefined, u(a(""), "")) },
-        { json: "calculate", js: "calculate", typ: u(undefined, "") },
+        { json: "calculate", js: "calculate", typ: "" },
         { json: "default", js: "default", typ: u(undefined, "") },
-        { json: "from", js: "from", typ: u(undefined, r("LookupData")) },
-        { json: "lookup", js: "lookup", typ: u(undefined, "") },
-        { json: "bin", js: "bin", typ: u(undefined, u(true, r("BinParams"))) },
-        { json: "field", js: "field", typ: u(undefined, "") },
-        { json: "timeUnit", js: "timeUnit", typ: u(undefined, r("TimeUnit")) },
-        { json: "aggregate", js: "aggregate", typ: u(undefined, a(r("AggregatedFieldDef"))) },
+        { json: "from", js: "from", typ: r("LookupData") },
+        { json: "lookup", js: "lookup", typ: "" },
+        { json: "bin", js: "bin", typ: u(true, r("BinParams")) },
+        { json: "field", js: "field", typ: "" },
+        { json: "timeUnit", js: "timeUnit", typ: r("TimeUnit") },
+        { json: "aggregate", js: "aggregate", typ: a(r("AggregatedFieldDef")) },
         { json: "groupby", js: "groupby", typ: u(undefined, a("")) },
     ], false),
     "AggregatedFieldDef": o([
diff --git a/head/schema-kotlin/test/inputs/schema/required-in-any-of.schema/default/TopLevel.kt b/head/schema-kotlin/test/inputs/schema/required-in-any-of.schema/default/TopLevel.kt
new file mode 100644
index 0000000..2222ac4
--- /dev/null
+++ b/head/schema-kotlin/test/inputs/schema/required-in-any-of.schema/default/TopLevel.kt
@@ -0,0 +1,24 @@
+// To parse the JSON, install Klaxon and do:
+//
+//   val topLevel = TopLevel.fromJson(jsonString)
+
+package quicktype
+
+import com.beust.klaxon.*
+
+private val klaxon = Klaxon()
+
+data class TopLevel (
+    val anyof: Anyof
+) {
+    public fun toJson() = klaxon.toJsonString(this)
+
+    companion object {
+        public fun fromJson(json: String) = klaxon.parse<TopLevel>(json)
+    }
+}
+
+data class Anyof (
+    val name: String,
+    val size: String? = null
+)
diff --git a/base/schema-kotlin/test/inputs/schema/vega-lite.schema/default/TopLevel.kt b/head/schema-kotlin/test/inputs/schema/vega-lite.schema/default/TopLevel.kt
index 31c56c7..9e16eac 100644
--- a/base/schema-kotlin/test/inputs/schema/vega-lite.schema/default/TopLevel.kt
+++ b/head/schema-kotlin/test/inputs/schema/vega-lite.schema/default/TopLevel.kt
@@ -136,7 +136,7 @@ data class TopLevel (
     /**
      * A key-value mapping between encoding channels and definition of fields.
      */
-    val encoding: EncodingWithFacet? = null,
+    val encoding: EncodingWithFacet,
 
     /**
      * The height of a visualization.
@@ -165,7 +165,7 @@ data class TopLevel (
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      */
-    val mark: AnyMark? = null,
+    val mark: AnyMark,
 
     /**
      * Name of the visualization for later reference.
@@ -235,7 +235,7 @@ data class TopLevel (
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      */
-    val layer: List<LayerSpec>? = null,
+    val layer: List<LayerSpec>,
 
     /**
      * Scale, axis, and legend resolutions for layers.
@@ -254,28 +254,28 @@ data class TopLevel (
      * An object that describes mappings between `row` and `column` channels and their field
      * definitions.
      */
-    val facet: FacetMapping? = null,
+    val facet: FacetMapping,
 
     /**
      * A specification of the view that gets faceted.
      */
-    val spec: Spec? = null,
+    val spec: Spec,
 
     /**
      * An object that describes what fields should be repeated into views that are laid out as a
      * `row` or `column`.
      */
-    val repeat: Repeat? = null,
+    val repeat: Repeat,
 
     /**
      * A list of views that should be concatenated and put into a column.
      */
-    val vconcat: List<Spec>? = null,
+    val vconcat: List<Spec>,
 
     /**
      * A list of views that should be concatenated and put into a row.
      */
-    val hconcat: List<Spec>? = null
+    val hconcat: List<Spec>
 ) {
     public fun toJson() = klaxon.toJsonString(this)
 
@@ -2387,7 +2387,7 @@ sealed class RangeConfigValue {
 data class VGScheme (
     val count: Double? = null,
     val extent: List<Double>? = null,
-    val scheme: String? = null,
+    val scheme: String,
     val step: Double? = null
 )
 
@@ -2964,7 +2964,7 @@ data class SingleSelectionConfig (
 data class VGBinding (
     val element: String? = null,
     val input: String,
-    val options: List<String>? = null,
+    val options: List<String>,
     val max: Double? = null,
     val min: Double? = null,
     val step: Double? = null
@@ -3859,7 +3859,7 @@ data class Data (
      * An URL from which to load the data set. Use the `format.type` property
      * to ensure the loaded data is correctly parsed.
      */
-    val url: String? = null,
+    val url: String,
 
     /**
      * The full data set, included inline. This can be an array of objects or primitive values
@@ -3867,12 +3867,12 @@ data class Data (
      * Arrays of primitive values are ingested as objects with a `data` property. Strings are
      * parsed according to the specified format type.
      */
-    val values: Values? = null,
+    val values: Values,
 
     /**
      * Provide a placeholder name and bind data at runtime.
      */
-    val name: String? = null
+    val name: String
 )
 
 /**
@@ -4273,7 +4273,7 @@ data class MarkPropDefWithCondition (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val type: Type? = null,
+    val type: Type,
 
     /**
      * A constant value in visual domain.
@@ -4447,7 +4447,7 @@ sealed class ColorCondition {
 }
 
 data class ConditionalValueDef (
-    val test: LogicalOperandPredicate? = null,
+    val test: LogicalOperandPredicate,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
@@ -4459,13 +4459,13 @@ data class ConditionalValueDef (
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
-    val selection: SelectionOperand? = null
+    val selection: SelectionOperand
 )
 
 data class Selection (
-    val not: SelectionOperand? = null,
-    val and: List<SelectionOperand>? = null,
-    val or: List<SelectionOperand>? = null
+    val not: SelectionOperand,
+    val and: List<SelectionOperand>,
+    val or: List<SelectionOperand>
 )
 
 /**
@@ -4493,21 +4493,21 @@ sealed class SelectionOperand {
 }
 
 data class Predicate (
-    val not: LogicalOperandPredicate? = null,
-    val and: List<LogicalOperandPredicate>? = null,
-    val or: List<LogicalOperandPredicate>? = null,
+    val not: LogicalOperandPredicate,
+    val and: List<LogicalOperandPredicate>,
+    val or: List<LogicalOperandPredicate>,
 
     /**
      * The value that the field should be equal to.
      */
-    val equal: Equal? = null,
+    val equal: Equal,
 
     /**
      * Field to be filtered.
      *
      * Field to be filtered
      */
-    val field: String? = null,
+    val field: String,
 
     /**
      * Time unit for the field to be filtered.
@@ -4520,18 +4520,18 @@ data class Predicate (
      * An array of inclusive minimum and maximum values
      * for a field value of a data item to be included in the filtered data.
      */
-    val range: List<RangeElement>? = null,
+    val range: List<RangeElement>,
 
     /**
      * A set of values that the `field`'s value should be a member of,
      * for a data item included in the filtered data.
      */
-    val oneOf: List<Equal>? = null,
+    val oneOf: List<Equal>,
 
     /**
      * Filter using a selection name.
      */
-    val selection: SelectionOperand? = null
+    val selection: SelectionOperand
 )
 
 /**
@@ -4860,19 +4860,19 @@ sealed class ConditionalValueDefValue {
 }
 
 data class ConditionalPredicateMarkPropFieldDefClass (
-    val test: LogicalOperandPredicate? = null,
+    val test: LogicalOperandPredicate,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    val value: ConditionalValueDefValue? = null,
+    val value: ConditionalValueDefValue,
 
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
-    val selection: SelectionOperand? = null,
+    val selection: SelectionOperand,
 
     /**
      * Aggregation function for the field
@@ -4946,7 +4946,7 @@ data class ConditionalPredicateMarkPropFieldDefClass (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val type: Type? = null
+    val type: Type
 )
 
 sealed class Field {
@@ -6017,7 +6017,7 @@ data class DefWithCondition (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val type: Type? = null,
+    val type: Type,
 
     /**
      * A constant value in visual domain.
@@ -6044,19 +6044,19 @@ sealed class HrefCondition {
 }
 
 data class ConditionalPredicateFieldDefClass (
-    val test: LogicalOperandPredicate? = null,
+    val test: LogicalOperandPredicate,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    val value: ConditionalValueDefValue? = null,
+    val value: ConditionalValueDefValue,
 
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
-    val selection: SelectionOperand? = null,
+    val selection: SelectionOperand,
 
     /**
      * Aggregation function for the field
@@ -6103,7 +6103,7 @@ data class ConditionalPredicateFieldDefClass (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val type: Type? = null
+    val type: Type
 )
 
 sealed class Order {
@@ -6259,7 +6259,7 @@ data class TextDefWithCondition (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val type: Type? = null,
+    val type: Type,
 
     /**
      * A constant value in visual domain.
@@ -6286,19 +6286,19 @@ sealed class TextCondition {
 }
 
 data class ConditionalPredicateTextFieldDefClass (
-    val test: LogicalOperandPredicate? = null,
+    val test: LogicalOperandPredicate,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    val value: ConditionalValueDefValue? = null,
+    val value: ConditionalValueDefValue,
 
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
-    val selection: SelectionOperand? = null,
+    val selection: SelectionOperand,
 
     /**
      * Aggregation function for the field
@@ -6351,7 +6351,7 @@ data class ConditionalPredicateTextFieldDefClass (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val type: Type? = null
+    val type: Type
 )
 
 /**
@@ -6458,13 +6458,13 @@ data class XClass (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val type: Type? = null,
+    val type: Type,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    val value: ConditionalValueDefValue? = null
+    val value: ConditionalValueDefValue
 )
 
 data class Axis (
@@ -6728,13 +6728,13 @@ data class X2Class (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val type: Type? = null,
+    val type: Type,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    val value: ConditionalValueDefValue? = null
+    val value: ConditionalValueDefValue
 )
 
 /**
@@ -6794,7 +6794,7 @@ data class Spec (
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      */
-    val layer: List<LayerSpec>? = null,
+    val layer: List<LayerSpec>,
 
     /**
      * Name of the visualization for later reference.
@@ -6851,7 +6851,7 @@ data class Spec (
     /**
      * A key-value mapping between encoding channels and definition of fields.
      */
-    val encoding: Encoding? = null,
+    val encoding: Encoding,
 
     /**
      * A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
@@ -6859,7 +6859,7 @@ data class Spec (
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      */
-    val mark: AnyMark? = null,
+    val mark: AnyMark,
 
     /**
      * An object defining properties of geographic projection.
@@ -6878,28 +6878,28 @@ data class Spec (
      * An object that describes mappings between `row` and `column` channels and their field
      * definitions.
      */
-    val facet: FacetMapping? = null,
+    val facet: FacetMapping,
 
     /**
      * A specification of the view that gets faceted.
      */
-    val spec: Spec? = null,
+    val spec: Spec,
 
     /**
      * An object that describes what fields should be repeated into views that are laid out as a
      * `row` or `column`.
      */
-    val repeat: Repeat? = null,
+    val repeat: Repeat,
 
     /**
      * A list of views that should be concatenated and put into a column.
      */
-    val vconcat: List<Spec>? = null,
+    val vconcat: List<Spec>,
 
     /**
      * A list of views that should be concatenated and put into a row.
      */
-    val hconcat: List<Spec>? = null
+    val hconcat: List<Spec>
 )
 
 /**
@@ -7039,7 +7039,7 @@ data class LayerSpec (
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      */
-    val layer: List<LayerSpec>? = null,
+    val layer: List<LayerSpec>,
 
     /**
      * Name of the visualization for later reference.
@@ -7088,7 +7088,7 @@ data class LayerSpec (
     /**
      * A key-value mapping between encoding channels and definition of fields.
      */
-    val encoding: Encoding? = null,
+    val encoding: Encoding,
 
     /**
      * A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
@@ -7096,7 +7096,7 @@ data class LayerSpec (
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      */
-    val mark: AnyMark? = null,
+    val mark: AnyMark,
 
     /**
      * An object defining properties of geographic projection.
@@ -7781,7 +7781,7 @@ data class Transform (
      * (3) a [selection predicate](filter.html#selection-predicate);
      * or (4) a logical operand that combines (1), (2), or (3).
      */
-    val filter: LogicalOperandPredicate? = null,
+    val filter: LogicalOperandPredicate,
 
     /**
      * The field for storing the computed formula value.
@@ -7802,7 +7802,7 @@ data class Transform (
      * A [expression](types.html#expression) string. Use the variable `datum` to refer to the
      * current data object.
      */
-    val calculate: String? = null,
+    val calculate: String,
 
     /**
      * The default value to use if lookup fails.
@@ -7814,34 +7814,34 @@ data class Transform (
     /**
      * Secondary data reference.
      */
-    val from: LookupData? = null,
+    val from: LookupData,
 
     /**
      * Key in primary data source.
      */
-    val lookup: String? = null,
+    val lookup: String,
 
     /**
      * An object indicating bin properties, or simply `true` for using default bin parameters.
      */
-    val bin: Bin? = null,
+    val bin: Bin,
 
     /**
      * The data field to bin.
      *
      * The data field to apply time unit.
      */
-    val field: String? = null,
+    val field: String,
 
     /**
      * The timeUnit.
      */
-    val timeUnit: TimeUnit? = null,
+    val timeUnit: TimeUnit,
 
     /**
      * Array of objects that define fields to aggregate.
      */
-    val aggregate: List<AggregatedFieldDef>? = null,
+    val aggregate: List<AggregatedFieldDef>,
 
     /**
      * The data fields to group by. If not specified, a single group containing all data objects
diff --git a/head/schema-kotlin-jackson/test/inputs/schema/required-in-any-of.schema/default/TopLevel.kt b/head/schema-kotlin-jackson/test/inputs/schema/required-in-any-of.schema/default/TopLevel.kt
new file mode 100644
index 0000000..b5f8c40
--- /dev/null
+++ b/head/schema-kotlin-jackson/test/inputs/schema/required-in-any-of.schema/default/TopLevel.kt
@@ -0,0 +1,37 @@
+// To parse the JSON, install jackson-module-kotlin and do:
+//
+//   val topLevel = TopLevel.fromJson(jsonString)
+
+package quicktype
+
+import com.fasterxml.jackson.annotation.*
+import com.fasterxml.jackson.core.*
+import com.fasterxml.jackson.databind.*
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer
+import com.fasterxml.jackson.databind.module.SimpleModule
+import com.fasterxml.jackson.databind.node.*
+import com.fasterxml.jackson.databind.ser.std.StdSerializer
+import com.fasterxml.jackson.module.kotlin.*
+
+val mapper = jacksonObjectMapper().apply {
+    propertyNamingStrategy = PropertyNamingStrategy.LOWER_CAMEL_CASE
+    setSerializationInclusion(JsonInclude.Include.NON_NULL)
+}
+
+data class TopLevel (
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val anyof: Anyof
+) {
+    fun toJson() = mapper.writeValueAsString(this)
+
+    companion object {
+        fun fromJson(json: String) = mapper.readValue<TopLevel>(json)
+    }
+}
+
+data class Anyof (
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val name: String,
+
+    val size: String? = null
+)
diff --git a/base/schema-kotlin-jackson/test/inputs/schema/vega-lite.schema/default/TopLevel.kt b/head/schema-kotlin-jackson/test/inputs/schema/vega-lite.schema/default/TopLevel.kt
index bd9d865..ec476de 100644
--- a/base/schema-kotlin-jackson/test/inputs/schema/vega-lite.schema/default/TopLevel.kt
+++ b/head/schema-kotlin-jackson/test/inputs/schema/vega-lite.schema/default/TopLevel.kt
@@ -149,7 +149,8 @@ data class TopLevel (
     /**
      * A key-value mapping between encoding channels and definition of fields.
      */
-    val encoding: EncodingWithFacet? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val encoding: EncodingWithFacet,
 
     /**
      * The height of a visualization.
@@ -178,7 +179,8 @@ data class TopLevel (
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      */
-    val mark: AnyMark? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val mark: AnyMark,
 
     /**
      * Name of the visualization for later reference.
@@ -248,7 +250,8 @@ data class TopLevel (
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      */
-    val layer: List<LayerSpec>? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val layer: List<LayerSpec>,
 
     /**
      * Scale, axis, and legend resolutions for layers.
@@ -267,28 +270,33 @@ data class TopLevel (
      * An object that describes mappings between `row` and `column` channels and their field
      * definitions.
      */
-    val facet: FacetMapping? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val facet: FacetMapping,
 
     /**
      * A specification of the view that gets faceted.
      */
-    val spec: Spec? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val spec: Spec,
 
     /**
      * An object that describes what fields should be repeated into views that are laid out as a
      * `row` or `column`.
      */
-    val repeat: Repeat? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val repeat: Repeat,
 
     /**
      * A list of views that should be concatenated and put into a column.
      */
-    val vconcat: List<Spec>? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val vconcat: List<Spec>,
 
     /**
      * A list of views that should be concatenated and put into a row.
      */
-    val hconcat: List<Spec>? = null
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val hconcat: List<Spec>
 ) {
     fun toJson() = mapper.writeValueAsString(this)
 
@@ -2400,7 +2408,10 @@ sealed class RangeConfigValue {
 data class VGScheme (
     val count: Double? = null,
     val extent: List<Double>? = null,
-    val scheme: String? = null,
+
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val scheme: String,
+
     val step: Double? = null
 )
 
@@ -2980,7 +2991,9 @@ data class VGBinding (
     @get:JsonProperty(required=true)@field:JsonProperty(required=true)
     val input: String,
 
-    val options: List<String>? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val options: List<String>,
+
     val max: Double? = null,
     val min: Double? = null,
     val step: Double? = null
@@ -3875,7 +3888,8 @@ data class Data (
      * An URL from which to load the data set. Use the `format.type` property
      * to ensure the loaded data is correctly parsed.
      */
-    val url: String? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val url: String,
 
     /**
      * The full data set, included inline. This can be an array of objects or primitive values
@@ -3883,12 +3897,14 @@ data class Data (
      * Arrays of primitive values are ingested as objects with a `data` property. Strings are
      * parsed according to the specified format type.
      */
-    val values: Values? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val values: Values,
 
     /**
      * Provide a placeholder name and bind data at runtime.
      */
-    val name: String? = null
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val name: String
 )
 
 /**
@@ -4289,7 +4305,8 @@ data class MarkPropDefWithCondition (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val type: Type? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val type: Type,
 
     /**
      * A constant value in visual domain.
@@ -4463,7 +4480,8 @@ sealed class ColorCondition {
 }
 
 data class ConditionalValueDef (
-    val test: LogicalOperandPredicate? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val test: LogicalOperandPredicate,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
@@ -4476,13 +4494,19 @@ data class ConditionalValueDef (
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
-    val selection: SelectionOperand? = null
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val selection: SelectionOperand
 )
 
 data class Selection (
-    val not: SelectionOperand? = null,
-    val and: List<SelectionOperand>? = null,
-    val or: List<SelectionOperand>? = null
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val not: SelectionOperand,
+
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val and: List<SelectionOperand>,
+
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val or: List<SelectionOperand>
 )
 
 /**
@@ -4510,21 +4534,28 @@ sealed class SelectionOperand {
 }
 
 data class Predicate (
-    val not: LogicalOperandPredicate? = null,
-    val and: List<LogicalOperandPredicate>? = null,
-    val or: List<LogicalOperandPredicate>? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val not: LogicalOperandPredicate,
+
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val and: List<LogicalOperandPredicate>,
+
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val or: List<LogicalOperandPredicate>,
 
     /**
      * The value that the field should be equal to.
      */
-    val equal: Equal? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val equal: Equal,
 
     /**
      * Field to be filtered.
      *
      * Field to be filtered
      */
-    val field: String? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val field: String,
 
     /**
      * Time unit for the field to be filtered.
@@ -4537,18 +4568,21 @@ data class Predicate (
      * An array of inclusive minimum and maximum values
      * for a field value of a data item to be included in the filtered data.
      */
-    val range: List<RangeElement>? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val range: List<RangeElement>,
 
     /**
      * A set of values that the `field`'s value should be a member of,
      * for a data item included in the filtered data.
      */
-    val oneOf: List<Equal>? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val oneOf: List<Equal>,
 
     /**
      * Filter using a selection name.
      */
-    val selection: SelectionOperand? = null
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val selection: SelectionOperand
 )
 
 /**
@@ -4877,19 +4911,22 @@ sealed class ConditionalValueDefValue {
 }
 
 data class ConditionalPredicateMarkPropFieldDefClass (
-    val test: LogicalOperandPredicate? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val test: LogicalOperandPredicate,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    val value: ConditionalValueDefValue? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val value: ConditionalValueDefValue,
 
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
-    val selection: SelectionOperand? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val selection: SelectionOperand,
 
     /**
      * Aggregation function for the field
@@ -4963,7 +5000,8 @@ data class ConditionalPredicateMarkPropFieldDefClass (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val type: Type? = null
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val type: Type
 )
 
 sealed class Field {
@@ -6045,7 +6083,8 @@ data class DefWithCondition (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val type: Type? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val type: Type,
 
     /**
      * A constant value in visual domain.
@@ -6072,19 +6111,22 @@ sealed class HrefCondition {
 }
 
 data class ConditionalPredicateFieldDefClass (
-    val test: LogicalOperandPredicate? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val test: LogicalOperandPredicate,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    val value: ConditionalValueDefValue? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val value: ConditionalValueDefValue,
 
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
-    val selection: SelectionOperand? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val selection: SelectionOperand,
 
     /**
      * Aggregation function for the field
@@ -6131,7 +6173,8 @@ data class ConditionalPredicateFieldDefClass (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val type: Type? = null
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val type: Type
 )
 
 sealed class Order {
@@ -6288,7 +6331,8 @@ data class TextDefWithCondition (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val type: Type? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val type: Type,
 
     /**
      * A constant value in visual domain.
@@ -6315,19 +6359,22 @@ sealed class TextCondition {
 }
 
 data class ConditionalPredicateTextFieldDefClass (
-    val test: LogicalOperandPredicate? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val test: LogicalOperandPredicate,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    val value: ConditionalValueDefValue? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val value: ConditionalValueDefValue,
 
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
-    val selection: SelectionOperand? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val selection: SelectionOperand,
 
     /**
      * Aggregation function for the field
@@ -6380,7 +6427,8 @@ data class ConditionalPredicateTextFieldDefClass (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val type: Type? = null
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val type: Type
 )
 
 /**
@@ -6487,13 +6535,15 @@ data class XClass (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val type: Type? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val type: Type,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    val value: ConditionalValueDefValue? = null
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val value: ConditionalValueDefValue
 )
 
 data class Axis (
@@ -6757,13 +6807,15 @@ data class X2Class (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val type: Type? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val type: Type,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    val value: ConditionalValueDefValue? = null
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val value: ConditionalValueDefValue
 )
 
 /**
@@ -6823,7 +6875,8 @@ data class Spec (
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      */
-    val layer: List<LayerSpec>? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val layer: List<LayerSpec>,
 
     /**
      * Name of the visualization for later reference.
@@ -6880,7 +6933,8 @@ data class Spec (
     /**
      * A key-value mapping between encoding channels and definition of fields.
      */
-    val encoding: Encoding? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val encoding: Encoding,
 
     /**
      * A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
@@ -6888,7 +6942,8 @@ data class Spec (
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      */
-    val mark: AnyMark? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val mark: AnyMark,
 
     /**
      * An object defining properties of geographic projection.
@@ -6907,28 +6962,33 @@ data class Spec (
      * An object that describes mappings between `row` and `column` channels and their field
      * definitions.
      */
-    val facet: FacetMapping? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val facet: FacetMapping,
 
     /**
      * A specification of the view that gets faceted.
      */
-    val spec: Spec? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val spec: Spec,
 
     /**
      * An object that describes what fields should be repeated into views that are laid out as a
      * `row` or `column`.
      */
-    val repeat: Repeat? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val repeat: Repeat,
 
     /**
      * A list of views that should be concatenated and put into a column.
      */
-    val vconcat: List<Spec>? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val vconcat: List<Spec>,
 
     /**
      * A list of views that should be concatenated and put into a row.
      */
-    val hconcat: List<Spec>? = null
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val hconcat: List<Spec>
 )
 
 /**
@@ -7068,7 +7128,8 @@ data class LayerSpec (
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      */
-    val layer: List<LayerSpec>? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val layer: List<LayerSpec>,
 
     /**
      * Name of the visualization for later reference.
@@ -7117,7 +7178,8 @@ data class LayerSpec (
     /**
      * A key-value mapping between encoding channels and definition of fields.
      */
-    val encoding: Encoding? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val encoding: Encoding,
 
     /**
      * A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
@@ -7125,7 +7187,8 @@ data class LayerSpec (
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      */
-    val mark: AnyMark? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val mark: AnyMark,
 
     /**
      * An object defining properties of geographic projection.
@@ -7813,7 +7876,8 @@ data class Transform (
      * (3) a [selection predicate](filter.html#selection-predicate);
      * or (4) a logical operand that combines (1), (2), or (3).
      */
-    val filter: LogicalOperandPredicate? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val filter: LogicalOperandPredicate,
 
     /**
      * The field for storing the computed formula value.
@@ -7834,7 +7898,8 @@ data class Transform (
      * A [expression](types.html#expression) string. Use the variable `datum` to refer to the
      * current data object.
      */
-    val calculate: String? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val calculate: String,
 
     /**
      * The default value to use if lookup fails.
@@ -7846,34 +7911,40 @@ data class Transform (
     /**
      * Secondary data reference.
      */
-    val from: LookupData? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val from: LookupData,
 
     /**
      * Key in primary data source.
      */
-    val lookup: String? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val lookup: String,
 
     /**
      * An object indicating bin properties, or simply `true` for using default bin parameters.
      */
-    val bin: Bin? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val bin: Bin,
 
     /**
      * The data field to bin.
      *
      * The data field to apply time unit.
      */
-    val field: String? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val field: String,
 
     /**
      * The timeUnit.
      */
-    val timeUnit: TimeUnit? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val timeUnit: TimeUnit,
 
     /**
      * Array of objects that define fields to aggregate.
      */
-    val aggregate: List<AggregatedFieldDef>? = null,
+    @get:JsonProperty(required=true)@field:JsonProperty(required=true)
+    val aggregate: List<AggregatedFieldDef>,
 
     /**
      * The data fields to group by. If not specified, a single group containing all data objects
diff --git a/head/schema-kotlinx/test/inputs/schema/required-in-any-of.schema/default/TopLevel.kt b/head/schema-kotlinx/test/inputs/schema/required-in-any-of.schema/default/TopLevel.kt
new file mode 100644
index 0000000..c0311f8
--- /dev/null
+++ b/head/schema-kotlinx/test/inputs/schema/required-in-any-of.schema/default/TopLevel.kt
@@ -0,0 +1,22 @@
+// To parse the JSON, install kotlin's serialization plugin and do:
+//
+// val json     = Json { allowStructuredMapKeys = true }
+// val topLevel = json.parse(TopLevel.serializer(), jsonString)
+
+package quicktype
+
+import kotlinx.serialization.*
+import kotlinx.serialization.json.*
+import kotlinx.serialization.descriptors.*
+import kotlinx.serialization.encoding.*
+
+@Serializable
+data class TopLevel (
+    val anyof: Anyof
+)
+
+@Serializable
+data class Anyof (
+    val name: String,
+    val size: String? = null
+)
diff --git a/base/schema-kotlinx/test/inputs/schema/vega-lite.schema/default/TopLevel.kt b/head/schema-kotlinx/test/inputs/schema/vega-lite.schema/default/TopLevel.kt
index c155c12..a3a91c3 100644
--- a/base/schema-kotlinx/test/inputs/schema/vega-lite.schema/default/TopLevel.kt
+++ b/head/schema-kotlinx/test/inputs/schema/vega-lite.schema/default/TopLevel.kt
@@ -58,7 +58,7 @@ data class TopLevel (
     /**
      * A key-value mapping between encoding channels and definition of fields.
      */
-    val encoding: EncodingWithFacet? = null,
+    val encoding: EncodingWithFacet,
 
     /**
      * The height of a visualization.
@@ -87,7 +87,7 @@ data class TopLevel (
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      */
-    val mark: AnyMark? = null,
+    val mark: AnyMark,
 
     /**
      * Name of the visualization for later reference.
@@ -157,7 +157,7 @@ data class TopLevel (
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      */
-    val layer: List<LayerSpec>? = null,
+    val layer: List<LayerSpec>,
 
     /**
      * Scale, axis, and legend resolutions for layers.
@@ -176,28 +176,28 @@ data class TopLevel (
      * An object that describes mappings between `row` and `column` channels and their field
      * definitions.
      */
-    val facet: FacetMapping? = null,
+    val facet: FacetMapping,
 
     /**
      * A specification of the view that gets faceted.
      */
-    val spec: Spec? = null,
+    val spec: Spec,
 
     /**
      * An object that describes what fields should be repeated into views that are laid out as a
      * `row` or `column`.
      */
-    val repeat: Repeat? = null,
+    val repeat: Repeat,
 
     /**
      * A list of views that should be concatenated and put into a column.
      */
-    val vconcat: List<Spec>? = null,
+    val vconcat: List<Spec>,
 
     /**
      * A list of views that should be concatenated and put into a row.
      */
-    val hconcat: List<Spec>? = null
+    val hconcat: List<Spec>
 )
 
 /**
@@ -2067,7 +2067,7 @@ sealed class RangeConfigValue {
 data class VGScheme (
     val count: Double? = null,
     val extent: List<Double>? = null,
-    val scheme: String? = null,
+    val scheme: String,
     val step: Double? = null
 )
 
@@ -2600,7 +2600,7 @@ data class SingleSelectionConfig (
 data class VGBinding (
     val element: String? = null,
     val input: String,
-    val options: List<String>? = null,
+    val options: List<String>,
     val max: Double? = null,
     val min: Double? = null,
     val step: Double? = null
@@ -3476,7 +3476,7 @@ data class Data (
      * An URL from which to load the data set. Use the `format.type` property
      * to ensure the loaded data is correctly parsed.
      */
-    val url: String? = null,
+    val url: String,
 
     /**
      * The full data set, included inline. This can be an array of objects or primitive values
@@ -3484,12 +3484,12 @@ data class Data (
      * Arrays of primitive values are ingested as objects with a `data` property. Strings are
      * parsed according to the specified format type.
      */
-    val values: Values? = null,
+    val values: Values,
 
     /**
      * Provide a placeholder name and bind data at runtime.
      */
-    val name: String? = null
+    val name: String
 )
 
 /**
@@ -3836,7 +3836,7 @@ data class MarkPropDefWithCondition (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val type: Type? = null,
+    val type: Type,
 
     /**
      * A constant value in visual domain.
@@ -3962,7 +3962,7 @@ sealed class ColorCondition {
 
 @Serializable
 data class ConditionalValueDef (
-    val test: LogicalOperandPredicate? = null,
+    val test: LogicalOperandPredicate,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
@@ -3974,14 +3974,14 @@ data class ConditionalValueDef (
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
-    val selection: SelectionOperand? = null
+    val selection: SelectionOperand
 )
 
 @Serializable
 data class Selection (
-    val not: SelectionOperand? = null,
-    val and: List<SelectionOperand>? = null,
-    val or: List<SelectionOperand>? = null
+    val not: SelectionOperand,
+    val and: List<SelectionOperand>,
+    val or: List<SelectionOperand>
 )
 
 /**
@@ -3998,21 +3998,21 @@ sealed class SelectionOperand {
 
 @Serializable
 data class Predicate (
-    val not: LogicalOperandPredicate? = null,
-    val and: List<LogicalOperandPredicate>? = null,
-    val or: List<LogicalOperandPredicate>? = null,
+    val not: LogicalOperandPredicate,
+    val and: List<LogicalOperandPredicate>,
+    val or: List<LogicalOperandPredicate>,
 
     /**
      * The value that the field should be equal to.
      */
-    val equal: Equal? = null,
+    val equal: Equal,
 
     /**
      * Field to be filtered.
      *
      * Field to be filtered
      */
-    val field: String? = null,
+    val field: String,
 
     /**
      * Time unit for the field to be filtered.
@@ -4025,18 +4025,18 @@ data class Predicate (
      * An array of inclusive minimum and maximum values
      * for a field value of a data item to be included in the filtered data.
      */
-    val range: List<RangeElement>? = null,
+    val range: List<RangeElement>,
 
     /**
      * A set of values that the `field`'s value should be a member of,
      * for a data item included in the filtered data.
      */
-    val oneOf: List<Equal>? = null,
+    val oneOf: List<Equal>,
 
     /**
      * Filter using a selection name.
      */
-    val selection: SelectionOperand? = null
+    val selection: SelectionOperand
 )
 
 /**
@@ -4238,19 +4238,19 @@ sealed class ConditionalValueDefValue {
 
 @Serializable
 data class ConditionalPredicateMarkPropFieldDefClass (
-    val test: LogicalOperandPredicate? = null,
+    val test: LogicalOperandPredicate,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    val value: ConditionalValueDefValue? = null,
+    val value: ConditionalValueDefValue,
 
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
-    val selection: SelectionOperand? = null,
+    val selection: SelectionOperand,
 
     /**
      * Aggregation function for the field
@@ -4324,7 +4324,7 @@ data class ConditionalPredicateMarkPropFieldDefClass (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val type: Type? = null
+    val type: Type
 )
 
 @Serializable
@@ -5213,7 +5213,7 @@ data class DefWithCondition (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val type: Type? = null,
+    val type: Type,
 
     /**
      * A constant value in visual domain.
@@ -5229,19 +5229,19 @@ sealed class HrefCondition {
 
 @Serializable
 data class ConditionalPredicateFieldDefClass (
-    val test: LogicalOperandPredicate? = null,
+    val test: LogicalOperandPredicate,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    val value: ConditionalValueDefValue? = null,
+    val value: ConditionalValueDefValue,
 
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
-    val selection: SelectionOperand? = null,
+    val selection: SelectionOperand,
 
     /**
      * Aggregation function for the field
@@ -5288,7 +5288,7 @@ data class ConditionalPredicateFieldDefClass (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val type: Type? = null
+    val type: Type
 )
 
 @Serializable
@@ -5434,7 +5434,7 @@ data class TextDefWithCondition (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val type: Type? = null,
+    val type: Type,
 
     /**
      * A constant value in visual domain.
@@ -5450,19 +5450,19 @@ sealed class TextCondition {
 
 @Serializable
 data class ConditionalPredicateTextFieldDefClass (
-    val test: LogicalOperandPredicate? = null,
+    val test: LogicalOperandPredicate,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    val value: ConditionalValueDefValue? = null,
+    val value: ConditionalValueDefValue,
 
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
-    val selection: SelectionOperand? = null,
+    val selection: SelectionOperand,
 
     /**
      * Aggregation function for the field
@@ -5515,7 +5515,7 @@ data class ConditionalPredicateTextFieldDefClass (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val type: Type? = null
+    val type: Type
 )
 
 /**
@@ -5623,13 +5623,13 @@ data class XClass (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val type: Type? = null,
+    val type: Type,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    val value: ConditionalValueDefValue? = null
+    val value: ConditionalValueDefValue
 )
 
 @Serializable
@@ -5883,13 +5883,13 @@ data class X2Class (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val type: Type? = null,
+    val type: Type,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    val value: ConditionalValueDefValue? = null
+    val value: ConditionalValueDefValue
 )
 
 /**
@@ -5951,7 +5951,7 @@ data class Spec (
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      */
-    val layer: List<LayerSpec>? = null,
+    val layer: List<LayerSpec>,
 
     /**
      * Name of the visualization for later reference.
@@ -6008,7 +6008,7 @@ data class Spec (
     /**
      * A key-value mapping between encoding channels and definition of fields.
      */
-    val encoding: Encoding? = null,
+    val encoding: Encoding,
 
     /**
      * A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
@@ -6016,7 +6016,7 @@ data class Spec (
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      */
-    val mark: AnyMark? = null,
+    val mark: AnyMark,
 
     /**
      * An object defining properties of geographic projection.
@@ -6035,28 +6035,28 @@ data class Spec (
      * An object that describes mappings between `row` and `column` channels and their field
      * definitions.
      */
-    val facet: FacetMapping? = null,
+    val facet: FacetMapping,
 
     /**
      * A specification of the view that gets faceted.
      */
-    val spec: Spec? = null,
+    val spec: Spec,
 
     /**
      * An object that describes what fields should be repeated into views that are laid out as a
      * `row` or `column`.
      */
-    val repeat: Repeat? = null,
+    val repeat: Repeat,
 
     /**
      * A list of views that should be concatenated and put into a column.
      */
-    val vconcat: List<Spec>? = null,
+    val vconcat: List<Spec>,
 
     /**
      * A list of views that should be concatenated and put into a row.
      */
-    val hconcat: List<Spec>? = null
+    val hconcat: List<Spec>
 )
 
 /**
@@ -6198,7 +6198,7 @@ data class LayerSpec (
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      */
-    val layer: List<LayerSpec>? = null,
+    val layer: List<LayerSpec>,
 
     /**
      * Name of the visualization for later reference.
@@ -6247,7 +6247,7 @@ data class LayerSpec (
     /**
      * A key-value mapping between encoding channels and definition of fields.
      */
-    val encoding: Encoding? = null,
+    val encoding: Encoding,
 
     /**
      * A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
@@ -6255,7 +6255,7 @@ data class LayerSpec (
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      */
-    val mark: AnyMark? = null,
+    val mark: AnyMark,
 
     /**
      * An object defining properties of geographic projection.
@@ -6870,7 +6870,7 @@ data class Transform (
      * (3) a [selection predicate](filter.html#selection-predicate);
      * or (4) a logical operand that combines (1), (2), or (3).
      */
-    val filter: LogicalOperandPredicate? = null,
+    val filter: LogicalOperandPredicate,
 
     /**
      * The field for storing the computed formula value.
@@ -6891,7 +6891,7 @@ data class Transform (
      * A [expression](types.html#expression) string. Use the variable `datum` to refer to the
      * current data object.
      */
-    val calculate: String? = null,
+    val calculate: String,
 
     /**
      * The default value to use if lookup fails.
@@ -6903,34 +6903,34 @@ data class Transform (
     /**
      * Secondary data reference.
      */
-    val from: LookupData? = null,
+    val from: LookupData,
 
     /**
      * Key in primary data source.
      */
-    val lookup: String? = null,
+    val lookup: String,
 
     /**
      * An object indicating bin properties, or simply `true` for using default bin parameters.
      */
-    val bin: Bin? = null,
+    val bin: Bin,
 
     /**
      * The data field to bin.
      *
      * The data field to apply time unit.
      */
-    val field: String? = null,
+    val field: String,
 
     /**
      * The timeUnit.
      */
-    val timeUnit: TimeUnit? = null,
+    val timeUnit: TimeUnit,
 
     /**
      * Array of objects that define fields to aggregate.
      */
-    val aggregate: List<AggregatedFieldDef>? = null,
+    val aggregate: List<AggregatedFieldDef>,
 
     /**
      * The data fields to group by. If not specified, a single group containing all data objects
diff --git a/head/schema-php/test/inputs/schema/required-in-any-of.schema/default/TopLevel.php b/head/schema-php/test/inputs/schema/required-in-any-of.schema/default/TopLevel.php
new file mode 100644
index 0000000..cc52bce
--- /dev/null
+++ b/head/schema-php/test/inputs/schema/required-in-any-of.schema/default/TopLevel.php
@@ -0,0 +1,263 @@
+<?php
+declare(strict_types=1);
+
+// This is an autogenerated file:TopLevel
+
+class TopLevel {
+    private Anyof $anyof; // json:anyof Required
+
+    /**
+     * @param Anyof $anyof
+     */
+    public function __construct(Anyof $anyof) {
+        $this->anyof = $anyof;
+    }
+
+    /**
+     * @param stdClass $value
+     * @throws Exception
+     * @return Anyof
+     */
+    public static function fromAnyof(stdClass $value): Anyof {
+        return Anyof::from($value); /*class*/
+    }
+
+    /**
+     * @throws Exception
+     * @return stdClass
+     */
+    public function toAnyof(): stdClass {
+        if (TopLevel::validateAnyof($this->anyof))  {
+            return $this->anyof->to(); /*class*/
+        }
+        throw new Exception('never get to this TopLevel::anyof');
+    }
+
+    /**
+     * @param Anyof
+     * @return bool
+     * @throws Exception
+     */
+    public static function validateAnyof(Anyof $value): bool {
+        $value->validate();
+        return true;
+    }
+
+    /**
+     * @throws Exception
+     * @return Anyof
+     */
+    public function getAnyof(): Anyof {
+        if (TopLevel::validateAnyof($this->anyof))  {
+            return $this->anyof;
+        }
+        throw new Exception('never get to getAnyof TopLevel::anyof');
+    }
+
+    /**
+     * @return Anyof
+     */
+    public static function sampleAnyof(): Anyof {
+        return Anyof::sample(); /*31:anyof*/
+    }
+
+    /**
+     * @throws Exception
+     * @return bool
+     */
+    public function validate(): bool {
+        return TopLevel::validateAnyof($this->anyof);
+    }
+
+    /**
+     * @return stdClass
+     * @throws Exception
+     */
+    public function to(): stdClass  {
+        $out = new stdClass();
+        $out->{'anyof'} = $this->toAnyof();
+        return $out;
+    }
+
+    /**
+     * @param stdClass $obj
+     * @return TopLevel
+     * @throws Exception
+     */
+    public static function from(stdClass $obj): TopLevel {
+        return new TopLevel(
+         TopLevel::fromAnyof($obj->{'anyof'})
+        );
+    }
+
+    /**
+     * @return TopLevel
+     */
+    public static function sample(): TopLevel {
+        return new TopLevel(
+         TopLevel::sampleAnyof()
+        );
+    }
+}
+
+// This is an autogenerated file:Anyof
+
+class Anyof {
+    private string $name; // json:name Required
+    private ?string $size; // json:size Optional
+
+    /**
+     * @param string $name
+     * @param string|null $size
+     */
+    public function __construct(string $name, ?string $size) {
+        $this->name = $name;
+        $this->size = $size;
+    }
+
+    /**
+     * @param string $value
+     * @throws Exception
+     * @return string
+     */
+    public static function fromName(string $value): string {
+        return $value; /*string*/
+    }
+
+    /**
+     * @throws Exception
+     * @return string
+     */
+    public function toName(): string {
+        if (Anyof::validateName($this->name))  {
+            return $this->name; /*string*/
+        }
+        throw new Exception('never get to this Anyof::name');
+    }
+
+    /**
+     * @param string
+     * @return bool
+     * @throws Exception
+     */
+    public static function validateName(string $value): bool {
+        return true;
+    }
+
+    /**
+     * @throws Exception
+     * @return string
+     */
+    public function getName(): string {
+        if (Anyof::validateName($this->name))  {
+            return $this->name;
+        }
+        throw new Exception('never get to getName Anyof::name');
+    }
+
+    /**
+     * @return string
+     */
+    public static function sampleName(): string {
+        return 'Anyof::name::31'; /*31:name*/
+    }
+
+    /**
+     * @param ?string $value
+     * @throws Exception
+     * @return ?string
+     */
+    public static function fromSize(?string $value): ?string {
+        if (!is_null($value)) {
+            return $value; /*string*/
+        } else {
+            return  null;
+        }
+    }
+
+    /**
+     * @throws Exception
+     * @return ?string
+     */
+    public function toSize(): ?string {
+        if (Anyof::validateSize($this->size))  {
+            if (!is_null($this->size)) {
+                return $this->size; /*string*/
+            } else {
+                return  null;
+            }
+        }
+        throw new Exception('never get to this Anyof::size');
+    }
+
+    /**
+     * @param string|null
+     * @return bool
+     * @throws Exception
+     */
+    public static function validateSize(?string $value): bool {
+        if (!is_null($value)) {
+        }
+        return true;
+    }
+
+    /**
+     * @throws Exception
+     * @return ?string
+     */
+    public function getSize(): ?string {
+        if (Anyof::validateSize($this->size))  {
+            return $this->size;
+        }
+        throw new Exception('never get to getSize Anyof::size');
+    }
+
+    /**
+     * @return ?string
+     */
+    public static function sampleSize(): ?string {
+        return 'Anyof::size::32'; /*32:size*/
+    }
+
+    /**
+     * @throws Exception
+     * @return bool
+     */
+    public function validate(): bool {
+        return Anyof::validateName($this->name)
+        || Anyof::validateSize($this->size);
+    }
+
+    /**
+     * @return stdClass
+     * @throws Exception
+     */
+    public function to(): stdClass  {
+        $out = new stdClass();
+        $out->{'name'} = $this->toName();
+        $out->{'size'} = $this->toSize();
+        return $out;
+    }
+
+    /**
+     * @param stdClass $obj
+     * @return Anyof
+     * @throws Exception
+     */
+    public static function from(stdClass $obj): Anyof {
+        return new Anyof(
+         Anyof::fromName($obj->{'name'})
+        ,Anyof::fromSize($obj->{'size'})
+        );
+    }
+
+    /**
+     * @return Anyof
+     */
+    public static function sample(): Anyof {
+        return new Anyof(
+         Anyof::sampleName()
+        ,Anyof::sampleSize()
+        );
+    }
+}
diff --git a/base/schema-php/test/inputs/schema/vega-lite.schema/default/TopLevel.php b/head/schema-php/test/inputs/schema/vega-lite.schema/default/TopLevel.php
index 1fca381..94c6908 100644
--- a/base/schema-php/test/inputs/schema/vega-lite.schema/default/TopLevel.php
+++ b/head/schema-php/test/inputs/schema/vega-lite.schema/default/TopLevel.php
@@ -10,9 +10,9 @@ class TopLevel {
     private ?Config $config; // json:config Optional
     private ?Data $data; // json:data Optional
     private ?string $description; // json:description Optional
-    private ?EncodingWithFacet $encoding; // json:encoding Optional
+    private EncodingWithFacet $encoding; // json:encoding Required
     private ?float $height; // json:height Optional
-    private MarkDef|Mark|null $mark; // json:mark Optional
+    private MarkDef|Mark $mark; // json:mark Required
     private ?string $name; // json:name Optional
     private Padding|float|null $padding; // json:padding Optional
     private ?Projection $projection; // json:projection Optional
@@ -20,13 +20,13 @@ class TopLevel {
     private TitleParams|string|null $title; // json:title Optional
     private ?array $transform; // json:transform Optional
     private ?float $width; // json:width Optional
-    private ?array $layer; // json:layer Optional
+    private array $layer; // json:layer Required
     private ?Resolve $resolve; // json:resolve Optional
-    private ?FacetMapping $facet; // json:facet Optional
-    private ?Spec $spec; // json:spec Optional
-    private ?Repeat $repeat; // json:repeat Optional
-    private ?array $vconcat; // json:vconcat Optional
-    private ?array $hconcat; // json:hconcat Optional
+    private FacetMapping $facet; // json:facet Required
+    private Spec $spec; // json:spec Required
+    private Repeat $repeat; // json:repeat Required
+    private array $vconcat; // json:vconcat Required
+    private array $hconcat; // json:hconcat Required
 
     /**
      * @param string|null $schema
@@ -35,9 +35,9 @@ class TopLevel {
      * @param Config|null $config
      * @param Data|null $data
      * @param string|null $description
-     * @param EncodingWithFacet|null $encoding
+     * @param EncodingWithFacet $encoding
      * @param float|null $height
-     * @param MarkDef|Mark|null $mark
+     * @param MarkDef|Mark $mark
      * @param string|null $name
      * @param Padding|float|null $padding
      * @param Projection|null $projection
@@ -45,15 +45,15 @@ class TopLevel {
      * @param TitleParams|string|null $title
      * @param array|null $transform
      * @param float|null $width
-     * @param array|null $layer
+     * @param array $layer
      * @param Resolve|null $resolve
-     * @param FacetMapping|null $facet
-     * @param Spec|null $spec
-     * @param Repeat|null $repeat
-     * @param array|null $vconcat
-     * @param array|null $hconcat
+     * @param FacetMapping $facet
+     * @param Spec $spec
+     * @param Repeat $repeat
+     * @param array $vconcat
+     * @param array $hconcat
      */
-    public function __construct(?string $schema, AutoSizeParams|AutosizeType|null $autosize, ?string $background, ?Config $config, ?Data $data, ?string $description, ?EncodingWithFacet $encoding, ?float $height, MarkDef|Mark|null $mark, ?string $name, Padding|float|null $padding, ?Projection $projection, ?stdClass $selection, TitleParams|string|null $title, ?array $transform, ?float $width, ?array $layer, ?Resolve $resolve, ?FacetMapping $facet, ?Spec $spec, ?Repeat $repeat, ?array $vconcat, ?array $hconcat) {
+    public function __construct(?string $schema, AutoSizeParams|AutosizeType|null $autosize, ?string $background, ?Config $config, ?Data $data, ?string $description, EncodingWithFacet $encoding, ?float $height, MarkDef|Mark $mark, ?string $name, Padding|float|null $padding, ?Projection $projection, ?stdClass $selection, TitleParams|string|null $title, ?array $transform, ?float $width, array $layer, ?Resolve $resolve, FacetMapping $facet, Spec $spec, Repeat $repeat, array $vconcat, array $hconcat) {
         $this->schema = $schema;
         $this->autosize = $autosize;
         $this->background = $background;
@@ -563,31 +563,23 @@ class TopLevel {
     /**
      * A key-value mapping between encoding channels and definition of fields.
      *
-     * @param ?stdClass $value
+     * @param stdClass $value
      * @throws Exception
-     * @return ?EncodingWithFacet
+     * @return EncodingWithFacet
      */
-    public static function fromEncoding(?stdClass $value): ?EncodingWithFacet {
-        if (!is_null($value)) {
-            return EncodingWithFacet::from($value); /*class*/
-        } else {
-            return  null;
-        }
+    public static function fromEncoding(stdClass $value): EncodingWithFacet {
+        return EncodingWithFacet::from($value); /*class*/
     }
 
     /**
      * A key-value mapping between encoding channels and definition of fields.
      *
      * @throws Exception
-     * @return ?stdClass
+     * @return stdClass
      */
-    public function toEncoding(): ?stdClass {
+    public function toEncoding(): stdClass {
         if (TopLevel::validateEncoding($this->encoding))  {
-            if (!is_null($this->encoding)) {
-                return $this->encoding->to(); /*class*/
-            } else {
-                return  null;
-            }
+            return $this->encoding->to(); /*class*/
         }
         throw new Exception('never get to this TopLevel::encoding');
     }
@@ -595,14 +587,12 @@ class TopLevel {
     /**
      * A key-value mapping between encoding channels and definition of fields.
      *
-     * @param EncodingWithFacet|null
+     * @param EncodingWithFacet
      * @return bool
      * @throws Exception
      */
-    public static function validateEncoding(?EncodingWithFacet $value): bool {
-        if (!is_null($value)) {
-            $value->validate();
-        }
+    public static function validateEncoding(EncodingWithFacet $value): bool {
+        $value->validate();
         return true;
     }
 
@@ -610,9 +600,9 @@ class TopLevel {
      * A key-value mapping between encoding channels and definition of fields.
      *
      * @throws Exception
-     * @return ?EncodingWithFacet
+     * @return EncodingWithFacet
      */
-    public function getEncoding(): ?EncodingWithFacet {
+    public function getEncoding(): EncodingWithFacet {
         if (TopLevel::validateEncoding($this->encoding))  {
             return $this->encoding;
         }
@@ -622,9 +612,9 @@ class TopLevel {
     /**
      * A key-value mapping between encoding channels and definition of fields.
      *
-     * @return ?EncodingWithFacet
+     * @return EncodingWithFacet
      */
-    public static function sampleEncoding(): ?EncodingWithFacet {
+    public static function sampleEncoding(): EncodingWithFacet {
         return EncodingWithFacet::sample(); /*37:encoding*/
     }
 
@@ -781,14 +771,12 @@ class TopLevel {
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      *
-     * @param stdClass|string|null $value
+     * @param stdClass|string $value
      * @throws Exception
-     * @return MarkDef|Mark|null
+     * @return MarkDef|Mark
      */
-    public static function fromMark(stdClass|string|null $value): MarkDef|Mark|null {
-        if (is_null($value)) {
-            return $value; /*null*/
-        } elseif (is_object($value)) {
+    public static function fromMark(stdClass|string $value): MarkDef|Mark {
+        if (is_object($value)) {
             return MarkDef::from($value); /*class*/
         } elseif (is_string($value) && in_array($value, ['area', 'bar', 'line', 'point', 'text', 'tick', 'rect', 'rule', 'circle', 'square', 'geoshape'], true)) {
             return Mark::from($value); /*enum*/
@@ -804,13 +792,11 @@ class TopLevel {
      * object](mark.html#mark-def).
      *
      * @throws Exception
-     * @return stdClass|string|null
+     * @return stdClass|string
      */
-    public function toMark(): stdClass|string|null {
+    public function toMark(): stdClass|string {
         if (TopLevel::validateMark($this->mark))  {
-            if (is_null($this->mark)) {
-                return $this->mark; /*null*/
-            } elseif ($this->mark instanceof MarkDef) {
+            if ($this->mark instanceof MarkDef) {
                 return $this->mark->to(); /*class*/
             } elseif ($this->mark instanceof Mark) {
                 return Mark::to($this->mark); /*enum*/
@@ -827,16 +813,12 @@ class TopLevel {
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      *
-     * @param MarkDef|Mark|null
+     * @param MarkDef|Mark
      * @return bool
      * @throws Exception
      */
-    public static function validateMark(MarkDef|Mark|null $value): bool {
-        if (is_null($value)) {
-            if (!is_null($value)) {
-                throw new Exception("Attribute Error:TopLevel::mark");
-            }
-        } elseif ($value instanceof MarkDef) {
+    public static function validateMark(MarkDef|Mark $value): bool {
+        if ($value instanceof MarkDef) {
             $value->validate();
         } elseif ($value instanceof Mark) {
             Mark::to($value);
@@ -853,9 +835,9 @@ class TopLevel {
      * object](mark.html#mark-def).
      *
      * @throws Exception
-     * @return MarkDef|Mark|null
+     * @return MarkDef|Mark
      */
-    public function getMark(): MarkDef|Mark|null {
+    public function getMark(): MarkDef|Mark {
         if (TopLevel::validateMark($this->mark))  {
             return $this->mark;
         }
@@ -868,9 +850,9 @@ class TopLevel {
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      *
-     * @return MarkDef|Mark|null
+     * @return MarkDef|Mark
      */
-    public static function sampleMark(): MarkDef|Mark|null {
+    public static function sampleMark(): MarkDef|Mark {
         return MarkDef::sample(); /*39:mark*/
     }
 
@@ -1550,18 +1532,14 @@ class TopLevel {
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      *
-     * @param ?array $value
+     * @param array $value
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public static function fromLayer(?array $value): ?array {
-        if (!is_null($value)) {
-            return  array_map(function ($value) {
-                return LayerSpec::from($value); /*class*/
-            }, $value);
-        } else {
-            return  null;
-        }
+    public static function fromLayer(array $value): array {
+        return  array_map(function ($value) {
+            return LayerSpec::from($value); /*class*/
+        }, $value);
     }
 
     /**
@@ -1571,17 +1549,13 @@ class TopLevel {
      * layering facet specifications is not allowed.
      *
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function toLayer(): ?array {
+    public function toLayer(): array {
         if (TopLevel::validateLayer($this->layer))  {
-            if (!is_null($this->layer)) {
-                return array_map(function ($value) {
-                    return $value->to(); /*class*/
-                }, $this->layer);
-            } else {
-                return  null;
-            }
+            return array_map(function ($value) {
+                return $value->to(); /*class*/
+            }, $this->layer);
         }
         throw new Exception('never get to this TopLevel::layer');
     }
@@ -1592,19 +1566,17 @@ class TopLevel {
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      *
-     * @param array|null
+     * @param array
      * @return bool
      * @throws Exception
      */
-    public static function validateLayer(?array $value): bool {
-        if (!is_null($value)) {
-            if (!is_array($value)) {
-                throw new Exception("Attribute Error:TopLevel::layer");
-            }
-            array_walk($value, function($value_v) {
-                $value_v->validate();
-            });
+    public static function validateLayer(array $value): bool {
+        if (!is_array($value)) {
+            throw new Exception("Attribute Error:TopLevel::layer");
         }
+        array_walk($value, function($value_v) {
+            $value_v->validate();
+        });
         return true;
     }
 
@@ -1615,9 +1587,9 @@ class TopLevel {
      * layering facet specifications is not allowed.
      *
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function getLayer(): ?array {
+    public function getLayer(): array {
         if (TopLevel::validateLayer($this->layer))  {
             return $this->layer;
         }
@@ -1630,9 +1602,9 @@ class TopLevel {
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      *
-     * @return ?array
+     * @return array
      */
-    public static function sampleLayer(): ?array {
+    public static function sampleLayer(): array {
         return  array(
             LayerSpec::sample() /*47:*/
         ); /* 47:layer*/
@@ -1750,16 +1722,12 @@ class TopLevel {
      * An object that describes mappings between `row` and `column` channels and their field
      * definitions.
      *
-     * @param ?stdClass $value
+     * @param stdClass $value
      * @throws Exception
-     * @return ?FacetMapping
+     * @return FacetMapping
      */
-    public static function fromFacet(?stdClass $value): ?FacetMapping {
-        if (!is_null($value)) {
-            return FacetMapping::from($value); /*class*/
-        } else {
-            return  null;
-        }
+    public static function fromFacet(stdClass $value): FacetMapping {
+        return FacetMapping::from($value); /*class*/
     }
 
     /**
@@ -1767,15 +1735,11 @@ class TopLevel {
      * definitions.
      *
      * @throws Exception
-     * @return ?stdClass
+     * @return stdClass
      */
-    public function toFacet(): ?stdClass {
+    public function toFacet(): stdClass {
         if (TopLevel::validateFacet($this->facet))  {
-            if (!is_null($this->facet)) {
-                return $this->facet->to(); /*class*/
-            } else {
-                return  null;
-            }
+            return $this->facet->to(); /*class*/
         }
         throw new Exception('never get to this TopLevel::facet');
     }
@@ -1784,14 +1748,12 @@ class TopLevel {
      * An object that describes mappings between `row` and `column` channels and their field
      * definitions.
      *
-     * @param FacetMapping|null
+     * @param FacetMapping
      * @return bool
      * @throws Exception
      */
-    public static function validateFacet(?FacetMapping $value): bool {
-        if (!is_null($value)) {
-            $value->validate();
-        }
+    public static function validateFacet(FacetMapping $value): bool {
+        $value->validate();
         return true;
     }
 
@@ -1800,9 +1762,9 @@ class TopLevel {
      * definitions.
      *
      * @throws Exception
-     * @return ?FacetMapping
+     * @return FacetMapping
      */
-    public function getFacet(): ?FacetMapping {
+    public function getFacet(): FacetMapping {
         if (TopLevel::validateFacet($this->facet))  {
             return $this->facet;
         }
@@ -1813,40 +1775,32 @@ class TopLevel {
      * An object that describes mappings between `row` and `column` channels and their field
      * definitions.
      *
-     * @return ?FacetMapping
+     * @return FacetMapping
      */
-    public static function sampleFacet(): ?FacetMapping {
+    public static function sampleFacet(): FacetMapping {
         return FacetMapping::sample(); /*49:facet*/
     }
 
     /**
      * A specification of the view that gets faceted.
      *
-     * @param ?stdClass $value
+     * @param stdClass $value
      * @throws Exception
-     * @return ?Spec
+     * @return Spec
      */
-    public static function fromSpec(?stdClass $value): ?Spec {
-        if (!is_null($value)) {
-            return Spec::from($value); /*class*/
-        } else {
-            return  null;
-        }
+    public static function fromSpec(stdClass $value): Spec {
+        return Spec::from($value); /*class*/
     }
 
     /**
      * A specification of the view that gets faceted.
      *
      * @throws Exception
-     * @return ?stdClass
+     * @return stdClass
      */
-    public function toSpec(): ?stdClass {
+    public function toSpec(): stdClass {
         if (TopLevel::validateSpec($this->spec))  {
-            if (!is_null($this->spec)) {
-                return $this->spec->to(); /*class*/
-            } else {
-                return  null;
-            }
+            return $this->spec->to(); /*class*/
         }
         throw new Exception('never get to this TopLevel::spec');
     }
@@ -1854,14 +1808,12 @@ class TopLevel {
     /**
      * A specification of the view that gets faceted.
      *
-     * @param Spec|null
+     * @param Spec
      * @return bool
      * @throws Exception
      */
-    public static function validateSpec(?Spec $value): bool {
-        if (!is_null($value)) {
-            $value->validate();
-        }
+    public static function validateSpec(Spec $value): bool {
+        $value->validate();
         return true;
     }
 
@@ -1869,9 +1821,9 @@ class TopLevel {
      * A specification of the view that gets faceted.
      *
      * @throws Exception
-     * @return ?Spec
+     * @return Spec
      */
-    public function getSpec(): ?Spec {
+    public function getSpec(): Spec {
         if (TopLevel::validateSpec($this->spec))  {
             return $this->spec;
         }
@@ -1881,9 +1833,9 @@ class TopLevel {
     /**
      * A specification of the view that gets faceted.
      *
-     * @return ?Spec
+     * @return Spec
      */
-    public static function sampleSpec(): ?Spec {
+    public static function sampleSpec(): Spec {
         return Spec::sample(); /*50:spec*/
     }
 
@@ -1891,16 +1843,12 @@ class TopLevel {
      * An object that describes what fields should be repeated into views that are laid out as a
      * `row` or `column`.
      *
-     * @param ?stdClass $value
+     * @param stdClass $value
      * @throws Exception
-     * @return ?Repeat
+     * @return Repeat
      */
-    public static function fromRepeat(?stdClass $value): ?Repeat {
-        if (!is_null($value)) {
-            return Repeat::from($value); /*class*/
-        } else {
-            return  null;
-        }
+    public static function fromRepeat(stdClass $value): Repeat {
+        return Repeat::from($value); /*class*/
     }
 
     /**
@@ -1908,15 +1856,11 @@ class TopLevel {
      * `row` or `column`.
      *
      * @throws Exception
-     * @return ?stdClass
+     * @return stdClass
      */
-    public function toRepeat(): ?stdClass {
+    public function toRepeat(): stdClass {
         if (TopLevel::validateRepeat($this->repeat))  {
-            if (!is_null($this->repeat)) {
-                return $this->repeat->to(); /*class*/
-            } else {
-                return  null;
-            }
+            return $this->repeat->to(); /*class*/
         }
         throw new Exception('never get to this TopLevel::repeat');
     }
@@ -1925,14 +1869,12 @@ class TopLevel {
      * An object that describes what fields should be repeated into views that are laid out as a
      * `row` or `column`.
      *
-     * @param Repeat|null
+     * @param Repeat
      * @return bool
      * @throws Exception
      */
-    public static function validateRepeat(?Repeat $value): bool {
-        if (!is_null($value)) {
-            $value->validate();
-        }
+    public static function validateRepeat(Repeat $value): bool {
+        $value->validate();
         return true;
     }
 
@@ -1941,9 +1883,9 @@ class TopLevel {
      * `row` or `column`.
      *
      * @throws Exception
-     * @return ?Repeat
+     * @return Repeat
      */
-    public function getRepeat(): ?Repeat {
+    public function getRepeat(): Repeat {
         if (TopLevel::validateRepeat($this->repeat))  {
             return $this->repeat;
         }
@@ -1954,44 +1896,36 @@ class TopLevel {
      * An object that describes what fields should be repeated into views that are laid out as a
      * `row` or `column`.
      *
-     * @return ?Repeat
+     * @return Repeat
      */
-    public static function sampleRepeat(): ?Repeat {
+    public static function sampleRepeat(): Repeat {
         return Repeat::sample(); /*51:repeat*/
     }
 
     /**
      * A list of views that should be concatenated and put into a column.
      *
-     * @param ?array $value
+     * @param array $value
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public static function fromVconcat(?array $value): ?array {
-        if (!is_null($value)) {
-            return  array_map(function ($value) {
-                return Spec::from($value); /*class*/
-            }, $value);
-        } else {
-            return  null;
-        }
+    public static function fromVconcat(array $value): array {
+        return  array_map(function ($value) {
+            return Spec::from($value); /*class*/
+        }, $value);
     }
 
     /**
      * A list of views that should be concatenated and put into a column.
      *
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function toVconcat(): ?array {
+    public function toVconcat(): array {
         if (TopLevel::validateVconcat($this->vconcat))  {
-            if (!is_null($this->vconcat)) {
-                return array_map(function ($value) {
-                    return $value->to(); /*class*/
-                }, $this->vconcat);
-            } else {
-                return  null;
-            }
+            return array_map(function ($value) {
+                return $value->to(); /*class*/
+            }, $this->vconcat);
         }
         throw new Exception('never get to this TopLevel::vconcat');
     }
@@ -1999,19 +1933,17 @@ class TopLevel {
     /**
      * A list of views that should be concatenated and put into a column.
      *
-     * @param array|null
+     * @param array
      * @return bool
      * @throws Exception
      */
-    public static function validateVconcat(?array $value): bool {
-        if (!is_null($value)) {
-            if (!is_array($value)) {
-                throw new Exception("Attribute Error:TopLevel::vconcat");
-            }
-            array_walk($value, function($value_v) {
-                $value_v->validate();
-            });
+    public static function validateVconcat(array $value): bool {
+        if (!is_array($value)) {
+            throw new Exception("Attribute Error:TopLevel::vconcat");
         }
+        array_walk($value, function($value_v) {
+            $value_v->validate();
+        });
         return true;
     }
 
@@ -2019,9 +1951,9 @@ class TopLevel {
      * A list of views that should be concatenated and put into a column.
      *
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function getVconcat(): ?array {
+    public function getVconcat(): array {
         if (TopLevel::validateVconcat($this->vconcat))  {
             return $this->vconcat;
         }
@@ -2031,9 +1963,9 @@ class TopLevel {
     /**
      * A list of views that should be concatenated and put into a column.
      *
-     * @return ?array
+     * @return array
      */
-    public static function sampleVconcat(): ?array {
+    public static function sampleVconcat(): array {
         return  array(
             Spec::sample() /*52:*/
         ); /* 52:vconcat*/
@@ -2042,35 +1974,27 @@ class TopLevel {
     /**
      * A list of views that should be concatenated and put into a row.
      *
-     * @param ?array $value
+     * @param array $value
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public static function fromHconcat(?array $value): ?array {
-        if (!is_null($value)) {
-            return  array_map(function ($value) {
-                return Spec::from($value); /*class*/
-            }, $value);
-        } else {
-            return  null;
-        }
+    public static function fromHconcat(array $value): array {
+        return  array_map(function ($value) {
+            return Spec::from($value); /*class*/
+        }, $value);
     }
 
     /**
      * A list of views that should be concatenated and put into a row.
      *
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function toHconcat(): ?array {
+    public function toHconcat(): array {
         if (TopLevel::validateHconcat($this->hconcat))  {
-            if (!is_null($this->hconcat)) {
-                return array_map(function ($value) {
-                    return $value->to(); /*class*/
-                }, $this->hconcat);
-            } else {
-                return  null;
-            }
+            return array_map(function ($value) {
+                return $value->to(); /*class*/
+            }, $this->hconcat);
         }
         throw new Exception('never get to this TopLevel::hconcat');
     }
@@ -2078,19 +2002,17 @@ class TopLevel {
     /**
      * A list of views that should be concatenated and put into a row.
      *
-     * @param array|null
+     * @param array
      * @return bool
      * @throws Exception
      */
-    public static function validateHconcat(?array $value): bool {
-        if (!is_null($value)) {
-            if (!is_array($value)) {
-                throw new Exception("Attribute Error:TopLevel::hconcat");
-            }
-            array_walk($value, function($value_v) {
-                $value_v->validate();
-            });
+    public static function validateHconcat(array $value): bool {
+        if (!is_array($value)) {
+            throw new Exception("Attribute Error:TopLevel::hconcat");
         }
+        array_walk($value, function($value_v) {
+            $value_v->validate();
+        });
         return true;
     }
 
@@ -2098,9 +2020,9 @@ class TopLevel {
      * A list of views that should be concatenated and put into a row.
      *
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function getHconcat(): ?array {
+    public function getHconcat(): array {
         if (TopLevel::validateHconcat($this->hconcat))  {
             return $this->hconcat;
         }
@@ -2110,9 +2032,9 @@ class TopLevel {
     /**
      * A list of views that should be concatenated and put into a row.
      *
-     * @return ?array
+     * @return array
      */
-    public static function sampleHconcat(): ?array {
+    public static function sampleHconcat(): array {
         return  array(
             Spec::sample() /*53:*/
         ); /* 53:hconcat*/
@@ -23081,16 +23003,16 @@ VGProjectionType::init();
 class VGScheme {
     private ?float $count; // json:count Optional
     private ?array $extent; // json:extent Optional
-    private ?string $scheme; // json:scheme Optional
+    private string $scheme; // json:scheme Required
     private ?float $step; // json:step Optional
 
     /**
      * @param float|null $count
      * @param array|null $extent
-     * @param string|null $scheme
+     * @param string $scheme
      * @param float|null $step
      */
-    public function __construct(?float $count, ?array $extent, ?string $scheme, ?float $step) {
+    public function __construct(?float $count, ?array $extent, string $scheme, ?float $step) {
         $this->count = $count;
         $this->extent = $extent;
         $this->scheme = $scheme;
@@ -23226,49 +23148,39 @@ class VGScheme {
     }
 
     /**
-     * @param ?string $value
+     * @param string $value
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public static function fromScheme(?string $value): ?string {
-        if (!is_null($value)) {
-            return $value; /*string*/
-        } else {
-            return  null;
-        }
+    public static function fromScheme(string $value): string {
+        return $value; /*string*/
     }
 
     /**
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public function toScheme(): ?string {
+    public function toScheme(): string {
         if (VGScheme::validateScheme($this->scheme))  {
-            if (!is_null($this->scheme)) {
-                return $this->scheme; /*string*/
-            } else {
-                return  null;
-            }
+            return $this->scheme; /*string*/
         }
         throw new Exception('never get to this VGScheme::scheme');
     }
 
     /**
-     * @param string|null
+     * @param string
      * @return bool
      * @throws Exception
      */
-    public static function validateScheme(?string $value): bool {
-        if (!is_null($value)) {
-        }
+    public static function validateScheme(string $value): bool {
         return true;
     }
 
     /**
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public function getScheme(): ?string {
+    public function getScheme(): string {
         if (VGScheme::validateScheme($this->scheme))  {
             return $this->scheme;
         }
@@ -23276,9 +23188,9 @@ class VGScheme {
     }
 
     /**
-     * @return ?string
+     * @return string
      */
-    public static function sampleScheme(): ?string {
+    public static function sampleScheme(): string {
         return 'VGScheme::scheme::33'; /*33:scheme*/
     }
 
@@ -28552,7 +28464,7 @@ class SingleSelectionConfig {
 class VGBinding {
     private ?string $element; // json:element Optional
     private string $input; // json:input Required
-    private ?array $options; // json:options Optional
+    private array $options; // json:options Required
     private ?float $max; // json:max Optional
     private ?float $min; // json:min Optional
     private ?float $step; // json:step Optional
@@ -28560,12 +28472,12 @@ class VGBinding {
     /**
      * @param string|null $element
      * @param string $input
-     * @param array|null $options
+     * @param array $options
      * @param float|null $max
      * @param float|null $min
      * @param float|null $step
      */
-    public function __construct(?string $element, string $input, ?array $options, ?float $max, ?float $min, ?float $step) {
+    public function __construct(?string $element, string $input, array $options, ?float $max, ?float $min, ?float $step) {
         $this->element = $element;
         $this->input = $input;
         $this->options = $options;
@@ -28679,61 +28591,51 @@ class VGBinding {
     }
 
     /**
-     * @param ?array $value
+     * @param array $value
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public static function fromOptions(?array $value): ?array {
-        if (!is_null($value)) {
-            return  array_map(function ($value) {
-                return $value; /*string*/
-            }, $value);
-        } else {
-            return  null;
-        }
+    public static function fromOptions(array $value): array {
+        return  array_map(function ($value) {
+            return $value; /*string*/
+        }, $value);
     }
 
     /**
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function toOptions(): ?array {
+    public function toOptions(): array {
         if (VGBinding::validateOptions($this->options))  {
-            if (!is_null($this->options)) {
-                return array_map(function ($value) {
-                    return $value; /*string*/
-                }, $this->options);
-            } else {
-                return  null;
-            }
+            return array_map(function ($value) {
+                return $value; /*string*/
+            }, $this->options);
         }
         throw new Exception('never get to this VGBinding::options');
     }
 
     /**
-     * @param array|null
+     * @param array
      * @return bool
      * @throws Exception
      */
-    public static function validateOptions(?array $value): bool {
-        if (!is_null($value)) {
-            if (!is_array($value)) {
+    public static function validateOptions(array $value): bool {
+        if (!is_array($value)) {
+            throw new Exception("Attribute Error:VGBinding::options");
+        }
+        array_walk($value, function($value_v) {
+            if (!is_string($value_v)) {
                 throw new Exception("Attribute Error:VGBinding::options");
             }
-            array_walk($value, function($value_v) {
-                if (!is_string($value_v)) {
-                    throw new Exception("Attribute Error:VGBinding::options");
-                }
-            });
-        }
+        });
         return true;
     }
 
     /**
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function getOptions(): ?array {
+    public function getOptions(): array {
         if (VGBinding::validateOptions($this->options))  {
             return $this->options;
         }
@@ -28741,9 +28643,9 @@ class VGBinding {
     }
 
     /**
-     * @return ?array
+     * @return array
      */
-    public static function sampleOptions(): ?array {
+    public static function sampleOptions(): array {
         return  array(
             'VGBinding::::33' /*33:*/
         ); /* 33:options*/
@@ -38845,17 +38747,17 @@ class ViewConfig {
 
 class Data {
     private ?DataFormat $format; // json:format Optional
-    private ?string $url; // json:url Optional
-    private stdClass|array|string|null $values; // json:values Optional
-    private ?string $name; // json:name Optional
+    private string $url; // json:url Required
+    private stdClass|array|string $values; // json:values Required
+    private string $name; // json:name Required
 
     /**
      * @param DataFormat|null $format
-     * @param string|null $url
-     * @param stdClass|array|string|null $values
-     * @param string|null $name
+     * @param string $url
+     * @param stdClass|array|string $values
+     * @param string $name
      */
-    public function __construct(?DataFormat $format, ?string $url, stdClass|array|string|null $values, ?string $name) {
+    public function __construct(?DataFormat $format, string $url, stdClass|array|string $values, string $name) {
         $this->format = $format;
         $this->url = $url;
         $this->values = $values;
@@ -38954,16 +38856,12 @@ class Data {
      * An URL from which to load the data set. Use the `format.type` property
      * to ensure the loaded data is correctly parsed.
      *
-     * @param ?string $value
+     * @param string $value
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public static function fromURL(?string $value): ?string {
-        if (!is_null($value)) {
-            return $value; /*string*/
-        } else {
-            return  null;
-        }
+    public static function fromURL(string $value): string {
+        return $value; /*string*/
     }
 
     /**
@@ -38971,15 +38869,11 @@ class Data {
      * to ensure the loaded data is correctly parsed.
      *
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public function toURL(): ?string {
+    public function toURL(): string {
         if (Data::validateURL($this->url))  {
-            if (!is_null($this->url)) {
-                return $this->url; /*string*/
-            } else {
-                return  null;
-            }
+            return $this->url; /*string*/
         }
         throw new Exception('never get to this Data::url');
     }
@@ -38988,13 +38882,11 @@ class Data {
      * An URL from which to load the data set. Use the `format.type` property
      * to ensure the loaded data is correctly parsed.
      *
-     * @param string|null
+     * @param string
      * @return bool
      * @throws Exception
      */
-    public static function validateURL(?string $value): bool {
-        if (!is_null($value)) {
-        }
+    public static function validateURL(string $value): bool {
         return true;
     }
 
@@ -39003,9 +38895,9 @@ class Data {
      * to ensure the loaded data is correctly parsed.
      *
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public function getURL(): ?string {
+    public function getURL(): string {
         if (Data::validateURL($this->url))  {
             return $this->url;
         }
@@ -39016,9 +38908,9 @@ class Data {
      * An URL from which to load the data set. Use the `format.type` property
      * to ensure the loaded data is correctly parsed.
      *
-     * @return ?string
+     * @return string
      */
-    public static function sampleURL(): ?string {
+    public static function sampleURL(): string {
         return 'Data::url::32'; /*32:url*/
     }
 
@@ -39028,14 +38920,12 @@ class Data {
      * Arrays of primitive values are ingested as objects with a `data` property. Strings are
      * parsed according to the specified format type.
      *
-     * @param stdClass|array|string|null $value
+     * @param stdClass|array|string $value
      * @throws Exception
-     * @return stdClass|array|string|null
+     * @return stdClass|array|string
      */
-    public static function fromValues(stdClass|array|string|null $value): stdClass|array|string|null {
-        if (is_null($value)) {
-            return $value; /*null*/
-        } elseif (is_object($value)) {
+    public static function fromValues(stdClass|array|string $value): stdClass|array|string {
+        if (is_object($value)) {
             $out = new stdClass();
             foreach ($value as $k => $v) {
                 $out->$k = $v; /*any*/
@@ -39073,13 +38963,11 @@ class Data {
      * parsed according to the specified format type.
      *
      * @throws Exception
-     * @return stdClass|array|string|null
+     * @return stdClass|array|string
      */
-    public function toValues(): stdClass|array|string|null {
+    public function toValues(): stdClass|array|string {
         if (Data::validateValues($this->values))  {
-            if (is_null($this->values)) {
-                return $this->values; /*null*/
-            } elseif ($this->values instanceof stdClass) {
+            if ($this->values instanceof stdClass) {
                 $out = new stdClass();
                 foreach ($this->values as $k => $v) {
                     $out->$k = $v; /*any*/
@@ -39118,16 +39006,12 @@ class Data {
      * Arrays of primitive values are ingested as objects with a `data` property. Strings are
      * parsed according to the specified format type.
      *
-     * @param stdClass|array|string|null
+     * @param stdClass|array|string
      * @return bool
      * @throws Exception
      */
-    public static function validateValues(stdClass|array|string|null $value): bool {
-        if (is_null($value)) {
-            if (!is_null($value)) {
-                throw new Exception("Attribute Error:Data::values");
-            }
-        } elseif ($value instanceof stdClass) {
+    public static function validateValues(stdClass|array|string $value): bool {
+        if ($value instanceof stdClass) {
             foreach ($value as $k => $v) {
             }
         } elseif (is_array($value)) {
@@ -39171,9 +39055,9 @@ class Data {
      * parsed according to the specified format type.
      *
      * @throws Exception
-     * @return stdClass|array|string|null
+     * @return stdClass|array|string
      */
-    public function getValues(): stdClass|array|string|null {
+    public function getValues(): stdClass|array|string {
         if (Data::validateValues($this->values))  {
             return $this->values;
         }
@@ -39186,9 +39070,9 @@ class Data {
      * Arrays of primitive values are ingested as objects with a `data` property. Strings are
      * parsed according to the specified format type.
      *
-     * @return stdClass|array|string|null
+     * @return stdClass|array|string
      */
-    public static function sampleValues(): stdClass|array|string|null {
+    public static function sampleValues(): stdClass|array|string {
         return  (function () {
             $out = new stdClass();
             $out->{'Data'} = 'AnyType::Data::values::33';/*33:values*/
@@ -39199,31 +39083,23 @@ class Data {
     /**
      * Provide a placeholder name and bind data at runtime.
      *
-     * @param ?string $value
+     * @param string $value
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public static function fromName(?string $value): ?string {
-        if (!is_null($value)) {
-            return $value; /*string*/
-        } else {
-            return  null;
-        }
+    public static function fromName(string $value): string {
+        return $value; /*string*/
     }
 
     /**
      * Provide a placeholder name and bind data at runtime.
      *
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public function toName(): ?string {
+    public function toName(): string {
         if (Data::validateName($this->name))  {
-            if (!is_null($this->name)) {
-                return $this->name; /*string*/
-            } else {
-                return  null;
-            }
+            return $this->name; /*string*/
         }
         throw new Exception('never get to this Data::name');
     }
@@ -39231,13 +39107,11 @@ class Data {
     /**
      * Provide a placeholder name and bind data at runtime.
      *
-     * @param string|null
+     * @param string
      * @return bool
      * @throws Exception
      */
-    public static function validateName(?string $value): bool {
-        if (!is_null($value)) {
-        }
+    public static function validateName(string $value): bool {
         return true;
     }
 
@@ -39245,9 +39119,9 @@ class Data {
      * Provide a placeholder name and bind data at runtime.
      *
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public function getName(): ?string {
+    public function getName(): string {
         if (Data::validateName($this->name))  {
             return $this->name;
         }
@@ -39257,9 +39131,9 @@ class Data {
     /**
      * Provide a placeholder name and bind data at runtime.
      *
-     * @return ?string
+     * @return string
      */
-    public static function sampleName(): ?string {
+    public static function sampleName(): string {
         return 'Data::name::34'; /*34:name*/
     }
 
@@ -41367,7 +41241,7 @@ class MarkPropDefWithCondition {
     private ?Scale $scale; // json:scale Optional
     private SortField|SortOrder|null $sort; // json:sort Optional
     private ?TimeUnit $timeUnit; // json:timeUnit Optional
-    private ?Type $type; // json:type Optional
+    private Type $type; // json:type Required
     private bool|float|string|null $value; // json:value Optional
 
     /**
@@ -41379,10 +41253,10 @@ class MarkPropDefWithCondition {
      * @param Scale|null $scale
      * @param SortField|SortOrder|null $sort
      * @param TimeUnit|null $timeUnit
-     * @param Type|null $type
+     * @param Type $type
      * @param bool|float|string|null $value
      */
-    public function __construct(?AggregateOp $aggregate, BinParams|bool|null $bin, ConditionalPredicateMarkPropFieldDefClass|array|null $condition, RepeatRef|string|null $field, ?Legend $legend, ?Scale $scale, SortField|SortOrder|null $sort, ?TimeUnit $timeUnit, ?Type $type, bool|float|string|null $value) {
+    public function __construct(?AggregateOp $aggregate, BinParams|bool|null $bin, ConditionalPredicateMarkPropFieldDefClass|array|null $condition, RepeatRef|string|null $field, ?Legend $legend, ?Scale $scale, SortField|SortOrder|null $sort, ?TimeUnit $timeUnit, Type $type, bool|float|string|null $value) {
         $this->aggregate = $aggregate;
         $this->bin = $bin;
         $this->condition = $condition;
@@ -42207,16 +42081,12 @@ class MarkPropDefWithCondition {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      *
-     * @param ?string $value
+     * @param string $value
      * @throws Exception
-     * @return ?Type
+     * @return Type
      */
-    public static function fromType(?string $value): ?Type {
-        if (!is_null($value)) {
-            return Type::from($value); /*enum*/
-        } else {
-            return  null;
-        }
+    public static function fromType(string $value): Type {
+        return Type::from($value); /*enum*/
     }
 
     /**
@@ -42226,15 +42096,11 @@ class MarkPropDefWithCondition {
      * [geographic projection](projection.html) is applied.
      *
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public function toType(): ?string {
+    public function toType(): string {
         if (MarkPropDefWithCondition::validateType($this->type))  {
-            if (!is_null($this->type)) {
-                return Type::to($this->type); /*enum*/
-            } else {
-                return  null;
-            }
+            return Type::to($this->type); /*enum*/
         }
         throw new Exception('never get to this MarkPropDefWithCondition::type');
     }
@@ -42245,14 +42111,12 @@ class MarkPropDefWithCondition {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      *
-     * @param Type|null
+     * @param Type
      * @return bool
      * @throws Exception
      */
-    public static function validateType(?Type $value): bool {
-        if (!is_null($value)) {
-            Type::to($value);
-        }
+    public static function validateType(Type $value): bool {
+        Type::to($value);
         return true;
     }
 
@@ -42263,9 +42127,9 @@ class MarkPropDefWithCondition {
      * [geographic projection](projection.html) is applied.
      *
      * @throws Exception
-     * @return ?Type
+     * @return Type
      */
-    public function getType(): ?Type {
+    public function getType(): Type {
         if (MarkPropDefWithCondition::validateType($this->type))  {
             return $this->type;
         }
@@ -42278,9 +42142,9 @@ class MarkPropDefWithCondition {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      *
-     * @return ?Type
+     * @return Type
      */
-    public static function sampleType(): ?Type {
+    public static function sampleType(): Type {
         return Type::sample(); /*enum*/
     }
 
@@ -43346,30 +43210,28 @@ class BinParams {
 // This is an autogenerated file:ConditionalValueDef
 
 class ConditionalValueDef {
-    private Predicate|string|null $test; // json:test Optional
+    private Predicate|string $test; // json:test Required
     private bool|float|string $value; // json:value Required
-    private Selection|string|null $selection; // json:selection Optional
+    private Selection|string $selection; // json:selection Required
 
     /**
-     * @param Predicate|string|null $test
+     * @param Predicate|string $test
      * @param bool|float|string $value
-     * @param Selection|string|null $selection
+     * @param Selection|string $selection
      */
-    public function __construct(Predicate|string|null $test, bool|float|string $value, Selection|string|null $selection) {
+    public function __construct(Predicate|string $test, bool|float|string $value, Selection|string $selection) {
         $this->test = $test;
         $this->value = $value;
         $this->selection = $selection;
     }
 
     /**
-     * @param stdClass|string|null $value
+     * @param stdClass|string $value
      * @throws Exception
-     * @return Predicate|string|null
+     * @return Predicate|string
      */
-    public static function fromTest(stdClass|string|null $value): Predicate|string|null {
-        if (is_null($value)) {
-            return $value; /*null*/
-        } elseif (is_object($value)) {
+    public static function fromTest(stdClass|string $value): Predicate|string {
+        if (is_object($value)) {
             return Predicate::from($value); /*class*/
         } elseif (is_string($value)) {
             return $value; /*string*/
@@ -43380,13 +43242,11 @@ class ConditionalValueDef {
 
     /**
      * @throws Exception
-     * @return stdClass|string|null
+     * @return stdClass|string
      */
-    public function toTest(): stdClass|string|null {
+    public function toTest(): stdClass|string {
         if (ConditionalValueDef::validateTest($this->test))  {
-            if (is_null($this->test)) {
-                return $this->test; /*null*/
-            } elseif ($this->test instanceof Predicate) {
+            if ($this->test instanceof Predicate) {
                 return $this->test->to(); /*class*/
             } elseif (is_string($this->test)) {
                 return $this->test; /*string*/
@@ -43398,16 +43258,12 @@ class ConditionalValueDef {
     }
 
     /**
-     * @param Predicate|string|null
+     * @param Predicate|string
      * @return bool
      * @throws Exception
      */
-    public static function validateTest(Predicate|string|null $value): bool {
-        if (is_null($value)) {
-            if (!is_null($value)) {
-                throw new Exception("Attribute Error:ConditionalValueDef::test");
-            }
-        } elseif ($value instanceof Predicate) {
+    public static function validateTest(Predicate|string $value): bool {
+        if ($value instanceof Predicate) {
             $value->validate();
         } elseif (is_string($value)) {
             if (!is_string($value)) {
@@ -43421,9 +43277,9 @@ class ConditionalValueDef {
 
     /**
      * @throws Exception
-     * @return Predicate|string|null
+     * @return Predicate|string
      */
-    public function getTest(): Predicate|string|null {
+    public function getTest(): Predicate|string {
         if (ConditionalValueDef::validateTest($this->test))  {
             return $this->test;
         }
@@ -43431,9 +43287,9 @@ class ConditionalValueDef {
     }
 
     /**
-     * @return Predicate|string|null
+     * @return Predicate|string
      */
-    public static function sampleTest(): Predicate|string|null {
+    public static function sampleTest(): Predicate|string {
         return Predicate::sample(); /*31:test*/
     }
 
@@ -43534,14 +43390,12 @@ class ConditionalValueDef {
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      *
-     * @param stdClass|string|null $value
+     * @param stdClass|string $value
      * @throws Exception
-     * @return Selection|string|null
+     * @return Selection|string
      */
-    public static function fromSelection(stdClass|string|null $value): Selection|string|null {
-        if (is_null($value)) {
-            return $value; /*null*/
-        } elseif (is_object($value)) {
+    public static function fromSelection(stdClass|string $value): Selection|string {
+        if (is_object($value)) {
             return Selection::from($value); /*class*/
         } elseif (is_string($value)) {
             return $value; /*string*/
@@ -43555,13 +43409,11 @@ class ConditionalValueDef {
      * selections](selection.html#compose).
      *
      * @throws Exception
-     * @return stdClass|string|null
+     * @return stdClass|string
      */
-    public function toSelection(): stdClass|string|null {
+    public function toSelection(): stdClass|string {
         if (ConditionalValueDef::validateSelection($this->selection))  {
-            if (is_null($this->selection)) {
-                return $this->selection; /*null*/
-            } elseif ($this->selection instanceof Selection) {
+            if ($this->selection instanceof Selection) {
                 return $this->selection->to(); /*class*/
             } elseif (is_string($this->selection)) {
                 return $this->selection; /*string*/
@@ -43576,16 +43428,12 @@ class ConditionalValueDef {
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      *
-     * @param Selection|string|null
+     * @param Selection|string
      * @return bool
      * @throws Exception
      */
-    public static function validateSelection(Selection|string|null $value): bool {
-        if (is_null($value)) {
-            if (!is_null($value)) {
-                throw new Exception("Attribute Error:ConditionalValueDef::selection");
-            }
-        } elseif ($value instanceof Selection) {
+    public static function validateSelection(Selection|string $value): bool {
+        if ($value instanceof Selection) {
             $value->validate();
         } elseif (is_string($value)) {
             if (!is_string($value)) {
@@ -43602,9 +43450,9 @@ class ConditionalValueDef {
      * selections](selection.html#compose).
      *
      * @throws Exception
-     * @return Selection|string|null
+     * @return Selection|string
      */
-    public function getSelection(): Selection|string|null {
+    public function getSelection(): Selection|string {
         if (ConditionalValueDef::validateSelection($this->selection))  {
             return $this->selection;
         }
@@ -43615,9 +43463,9 @@ class ConditionalValueDef {
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      *
-     * @return Selection|string|null
+     * @return Selection|string
      */
-    public static function sampleSelection(): Selection|string|null {
+    public static function sampleSelection(): Selection|string {
         return Selection::sample(); /*33:selection*/
     }
 
@@ -43671,30 +43519,28 @@ class ConditionalValueDef {
 // This is an autogenerated file:Selection
 
 class Selection {
-    private Selection|string|null $not; // json:not Optional
-    private ?array $and; // json:and Optional
-    private ?array $or; // json:or Optional
+    private Selection|string $not; // json:not Required
+    private array $and; // json:and Required
+    private array $or; // json:or Required
 
     /**
-     * @param Selection|string|null $not
-     * @param array|null $and
-     * @param array|null $or
+     * @param Selection|string $not
+     * @param array $and
+     * @param array $or
      */
-    public function __construct(Selection|string|null $not, ?array $and, ?array $or) {
+    public function __construct(Selection|string $not, array $and, array $or) {
         $this->not = $not;
         $this->and = $and;
         $this->or = $or;
     }
 
     /**
-     * @param stdClass|string|null $value
+     * @param stdClass|string $value
      * @throws Exception
-     * @return Selection|string|null
+     * @return Selection|string
      */
-    public static function fromNot(stdClass|string|null $value): Selection|string|null {
-        if (is_null($value)) {
-            return $value; /*null*/
-        } elseif (is_object($value)) {
+    public static function fromNot(stdClass|string $value): Selection|string {
+        if (is_object($value)) {
             return Selection::from($value); /*class*/
         } elseif (is_string($value)) {
             return $value; /*string*/
@@ -43705,13 +43551,11 @@ class Selection {
 
     /**
      * @throws Exception
-     * @return stdClass|string|null
+     * @return stdClass|string
      */
-    public function toNot(): stdClass|string|null {
+    public function toNot(): stdClass|string {
         if (Selection::validateNot($this->not))  {
-            if (is_null($this->not)) {
-                return $this->not; /*null*/
-            } elseif ($this->not instanceof Selection) {
+            if ($this->not instanceof Selection) {
                 return $this->not->to(); /*class*/
             } elseif (is_string($this->not)) {
                 return $this->not; /*string*/
@@ -43723,16 +43567,12 @@ class Selection {
     }
 
     /**
-     * @param Selection|string|null
+     * @param Selection|string
      * @return bool
      * @throws Exception
      */
-    public static function validateNot(Selection|string|null $value): bool {
-        if (is_null($value)) {
-            if (!is_null($value)) {
-                throw new Exception("Attribute Error:Selection::not");
-            }
-        } elseif ($value instanceof Selection) {
+    public static function validateNot(Selection|string $value): bool {
+        if ($value instanceof Selection) {
             $value->validate();
         } elseif (is_string($value)) {
             if (!is_string($value)) {
@@ -43746,9 +43586,9 @@ class Selection {
 
     /**
      * @throws Exception
-     * @return Selection|string|null
+     * @return Selection|string
      */
-    public function getNot(): Selection|string|null {
+    public function getNot(): Selection|string {
         if (Selection::validateNot($this->not))  {
             return $this->not;
         }
@@ -43756,86 +43596,76 @@ class Selection {
     }
 
     /**
-     * @return Selection|string|null
+     * @return Selection|string
      */
-    public static function sampleNot(): Selection|string|null {
+    public static function sampleNot(): Selection|string {
         return Selection::sample(); /*31:not*/
     }
 
     /**
-     * @param ?array $value
+     * @param array $value
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public static function fromAnd(?array $value): ?array {
-        if (!is_null($value)) {
-            return  array_map(function ($value) {
-                if (is_object($value)) {
-                    return Selection::from($value); /*class*/
-                } elseif (is_string($value)) {
-                    return $value; /*string*/
-                } else {
-                    throw new Exception('Cannot deserialize union value in Selection');
-                }
-            }, $value);
-        } else {
-            return  null;
-        }
+    public static function fromAnd(array $value): array {
+        return  array_map(function ($value) {
+            if (is_object($value)) {
+                return Selection::from($value); /*class*/
+            } elseif (is_string($value)) {
+                return $value; /*string*/
+            } else {
+                throw new Exception('Cannot deserialize union value in Selection');
+            }
+        }, $value);
     }
 
     /**
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function toAnd(): ?array {
+    public function toAnd(): array {
         if (Selection::validateAnd($this->and))  {
-            if (!is_null($this->and)) {
-                return array_map(function ($value) {
-                    if ($value instanceof Selection) {
-                        return $value->to(); /*class*/
-                    } elseif (is_string($value)) {
-                        return $value; /*string*/
-                    } else {
-                        throw new Exception('Union value has no matching member in Selection');
-                    }
-                }, $this->and);
-            } else {
-                return  null;
-            }
+            return array_map(function ($value) {
+                if ($value instanceof Selection) {
+                    return $value->to(); /*class*/
+                } elseif (is_string($value)) {
+                    return $value; /*string*/
+                } else {
+                    throw new Exception('Union value has no matching member in Selection');
+                }
+            }, $this->and);
         }
         throw new Exception('never get to this Selection::and');
     }
 
     /**
-     * @param array|null
+     * @param array
      * @return bool
      * @throws Exception
      */
-    public static function validateAnd(?array $value): bool {
-        if (!is_null($value)) {
-            if (!is_array($value)) {
-                throw new Exception("Attribute Error:Selection::and");
-            }
-            array_walk($value, function($value_v) {
-                if ($value_v instanceof Selection) {
-                    $value_v->validate();
-                } elseif (is_string($value_v)) {
-                    if (!is_string($value_v)) {
-                        throw new Exception("Attribute Error:Selection::and");
-                    }
-                } else {
+    public static function validateAnd(array $value): bool {
+        if (!is_array($value)) {
+            throw new Exception("Attribute Error:Selection::and");
+        }
+        array_walk($value, function($value_v) {
+            if ($value_v instanceof Selection) {
+                $value_v->validate();
+            } elseif (is_string($value_v)) {
+                if (!is_string($value_v)) {
                     throw new Exception("Attribute Error:Selection::and");
                 }
-            });
-        }
+            } else {
+                throw new Exception("Attribute Error:Selection::and");
+            }
+        });
         return true;
     }
 
     /**
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function getAnd(): ?array {
+    public function getAnd(): array {
         if (Selection::validateAnd($this->and))  {
             return $this->and;
         }
@@ -43843,88 +43673,78 @@ class Selection {
     }
 
     /**
-     * @return ?array
+     * @return array
      */
-    public static function sampleAnd(): ?array {
+    public static function sampleAnd(): array {
         return  array(
             Selection::sample() /*32:*/
         ); /* 32:and*/
     }
 
     /**
-     * @param ?array $value
+     * @param array $value
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public static function fromOr(?array $value): ?array {
-        if (!is_null($value)) {
-            return  array_map(function ($value) {
-                if (is_object($value)) {
-                    return Selection::from($value); /*class*/
-                } elseif (is_string($value)) {
-                    return $value; /*string*/
-                } else {
-                    throw new Exception('Cannot deserialize union value in Selection');
-                }
-            }, $value);
-        } else {
-            return  null;
-        }
+    public static function fromOr(array $value): array {
+        return  array_map(function ($value) {
+            if (is_object($value)) {
+                return Selection::from($value); /*class*/
+            } elseif (is_string($value)) {
+                return $value; /*string*/
+            } else {
+                throw new Exception('Cannot deserialize union value in Selection');
+            }
+        }, $value);
     }
 
     /**
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function toOr(): ?array {
+    public function toOr(): array {
         if (Selection::validateOr($this->or))  {
-            if (!is_null($this->or)) {
-                return array_map(function ($value) {
-                    if ($value instanceof Selection) {
-                        return $value->to(); /*class*/
-                    } elseif (is_string($value)) {
-                        return $value; /*string*/
-                    } else {
-                        throw new Exception('Union value has no matching member in Selection');
-                    }
-                }, $this->or);
-            } else {
-                return  null;
-            }
+            return array_map(function ($value) {
+                if ($value instanceof Selection) {
+                    return $value->to(); /*class*/
+                } elseif (is_string($value)) {
+                    return $value; /*string*/
+                } else {
+                    throw new Exception('Union value has no matching member in Selection');
+                }
+            }, $this->or);
         }
         throw new Exception('never get to this Selection::or');
     }
 
     /**
-     * @param array|null
+     * @param array
      * @return bool
      * @throws Exception
      */
-    public static function validateOr(?array $value): bool {
-        if (!is_null($value)) {
-            if (!is_array($value)) {
-                throw new Exception("Attribute Error:Selection::or");
-            }
-            array_walk($value, function($value_v) {
-                if ($value_v instanceof Selection) {
-                    $value_v->validate();
-                } elseif (is_string($value_v)) {
-                    if (!is_string($value_v)) {
-                        throw new Exception("Attribute Error:Selection::or");
-                    }
-                } else {
+    public static function validateOr(array $value): bool {
+        if (!is_array($value)) {
+            throw new Exception("Attribute Error:Selection::or");
+        }
+        array_walk($value, function($value_v) {
+            if ($value_v instanceof Selection) {
+                $value_v->validate();
+            } elseif (is_string($value_v)) {
+                if (!is_string($value_v)) {
                     throw new Exception("Attribute Error:Selection::or");
                 }
-            });
-        }
+            } else {
+                throw new Exception("Attribute Error:Selection::or");
+            }
+        });
         return true;
     }
 
     /**
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function getOr(): ?array {
+    public function getOr(): array {
         if (Selection::validateOr($this->or))  {
             return $this->or;
         }
@@ -43932,9 +43752,9 @@ class Selection {
     }
 
     /**
-     * @return ?array
+     * @return array
      */
-    public static function sampleOr(): ?array {
+    public static function sampleOr(): array {
         return  array(
             Selection::sample() /*33:*/
         ); /* 33:or*/
@@ -43990,28 +43810,28 @@ class Selection {
 // This is an autogenerated file:Predicate
 
 class Predicate {
-    private Predicate|string|null $not; // json:not Optional
-    private ?array $and; // json:and Optional
-    private ?array $or; // json:or Optional
-    private DateTimeClass|bool|float|string|null $equal; // json:equal Optional
-    private ?string $field; // json:field Optional
+    private Predicate|string $not; // json:not Required
+    private array $and; // json:and Required
+    private array $or; // json:or Required
+    private DateTimeClass|bool|float|string $equal; // json:equal Required
+    private string $field; // json:field Required
     private ?TimeUnit $timeUnit; // json:timeUnit Optional
-    private ?array $range; // json:range Optional
-    private ?array $oneOf; // json:oneOf Optional
-    private Selection|string|null $selection; // json:selection Optional
+    private array $range; // json:range Required
+    private array $oneOf; // json:oneOf Required
+    private Selection|string $selection; // json:selection Required
 
     /**
-     * @param Predicate|string|null $not
-     * @param array|null $and
-     * @param array|null $or
-     * @param DateTimeClass|bool|float|string|null $equal
-     * @param string|null $field
+     * @param Predicate|string $not
+     * @param array $and
+     * @param array $or
+     * @param DateTimeClass|bool|float|string $equal
+     * @param string $field
      * @param TimeUnit|null $timeUnit
-     * @param array|null $range
-     * @param array|null $oneOf
-     * @param Selection|string|null $selection
+     * @param array $range
+     * @param array $oneOf
+     * @param Selection|string $selection
      */
-    public function __construct(Predicate|string|null $not, ?array $and, ?array $or, DateTimeClass|bool|float|string|null $equal, ?string $field, ?TimeUnit $timeUnit, ?array $range, ?array $oneOf, Selection|string|null $selection) {
+    public function __construct(Predicate|string $not, array $and, array $or, DateTimeClass|bool|float|string $equal, string $field, ?TimeUnit $timeUnit, array $range, array $oneOf, Selection|string $selection) {
         $this->not = $not;
         $this->and = $and;
         $this->or = $or;
@@ -44024,14 +43844,12 @@ class Predicate {
     }
 
     /**
-     * @param stdClass|string|null $value
+     * @param stdClass|string $value
      * @throws Exception
-     * @return Predicate|string|null
+     * @return Predicate|string
      */
-    public static function fromNot(stdClass|string|null $value): Predicate|string|null {
-        if (is_null($value)) {
-            return $value; /*null*/
-        } elseif (is_object($value)) {
+    public static function fromNot(stdClass|string $value): Predicate|string {
+        if (is_object($value)) {
             return Predicate::from($value); /*class*/
         } elseif (is_string($value)) {
             return $value; /*string*/
@@ -44042,13 +43860,11 @@ class Predicate {
 
     /**
      * @throws Exception
-     * @return stdClass|string|null
+     * @return stdClass|string
      */
-    public function toNot(): stdClass|string|null {
+    public function toNot(): stdClass|string {
         if (Predicate::validateNot($this->not))  {
-            if (is_null($this->not)) {
-                return $this->not; /*null*/
-            } elseif ($this->not instanceof Predicate) {
+            if ($this->not instanceof Predicate) {
                 return $this->not->to(); /*class*/
             } elseif (is_string($this->not)) {
                 return $this->not; /*string*/
@@ -44060,16 +43876,12 @@ class Predicate {
     }
 
     /**
-     * @param Predicate|string|null
+     * @param Predicate|string
      * @return bool
      * @throws Exception
      */
-    public static function validateNot(Predicate|string|null $value): bool {
-        if (is_null($value)) {
-            if (!is_null($value)) {
-                throw new Exception("Attribute Error:Predicate::not");
-            }
-        } elseif ($value instanceof Predicate) {
+    public static function validateNot(Predicate|string $value): bool {
+        if ($value instanceof Predicate) {
             $value->validate();
         } elseif (is_string($value)) {
             if (!is_string($value)) {
@@ -44083,9 +43895,9 @@ class Predicate {
 
     /**
      * @throws Exception
-     * @return Predicate|string|null
+     * @return Predicate|string
      */
-    public function getNot(): Predicate|string|null {
+    public function getNot(): Predicate|string {
         if (Predicate::validateNot($this->not))  {
             return $this->not;
         }
@@ -44093,86 +43905,76 @@ class Predicate {
     }
 
     /**
-     * @return Predicate|string|null
+     * @return Predicate|string
      */
-    public static function sampleNot(): Predicate|string|null {
+    public static function sampleNot(): Predicate|string {
         return Predicate::sample(); /*31:not*/
     }
 
     /**
-     * @param ?array $value
+     * @param array $value
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public static function fromAnd(?array $value): ?array {
-        if (!is_null($value)) {
-            return  array_map(function ($value) {
-                if (is_object($value)) {
-                    return Predicate::from($value); /*class*/
-                } elseif (is_string($value)) {
-                    return $value; /*string*/
-                } else {
-                    throw new Exception('Cannot deserialize union value in Predicate');
-                }
-            }, $value);
-        } else {
-            return  null;
-        }
+    public static function fromAnd(array $value): array {
+        return  array_map(function ($value) {
+            if (is_object($value)) {
+                return Predicate::from($value); /*class*/
+            } elseif (is_string($value)) {
+                return $value; /*string*/
+            } else {
+                throw new Exception('Cannot deserialize union value in Predicate');
+            }
+        }, $value);
     }
 
     /**
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function toAnd(): ?array {
+    public function toAnd(): array {
         if (Predicate::validateAnd($this->and))  {
-            if (!is_null($this->and)) {
-                return array_map(function ($value) {
-                    if ($value instanceof Predicate) {
-                        return $value->to(); /*class*/
-                    } elseif (is_string($value)) {
-                        return $value; /*string*/
-                    } else {
-                        throw new Exception('Union value has no matching member in Predicate');
-                    }
-                }, $this->and);
-            } else {
-                return  null;
-            }
+            return array_map(function ($value) {
+                if ($value instanceof Predicate) {
+                    return $value->to(); /*class*/
+                } elseif (is_string($value)) {
+                    return $value; /*string*/
+                } else {
+                    throw new Exception('Union value has no matching member in Predicate');
+                }
+            }, $this->and);
         }
         throw new Exception('never get to this Predicate::and');
     }
 
     /**
-     * @param array|null
+     * @param array
      * @return bool
      * @throws Exception
      */
-    public static function validateAnd(?array $value): bool {
-        if (!is_null($value)) {
-            if (!is_array($value)) {
-                throw new Exception("Attribute Error:Predicate::and");
-            }
-            array_walk($value, function($value_v) {
-                if ($value_v instanceof Predicate) {
-                    $value_v->validate();
-                } elseif (is_string($value_v)) {
-                    if (!is_string($value_v)) {
-                        throw new Exception("Attribute Error:Predicate::and");
-                    }
-                } else {
+    public static function validateAnd(array $value): bool {
+        if (!is_array($value)) {
+            throw new Exception("Attribute Error:Predicate::and");
+        }
+        array_walk($value, function($value_v) {
+            if ($value_v instanceof Predicate) {
+                $value_v->validate();
+            } elseif (is_string($value_v)) {
+                if (!is_string($value_v)) {
                     throw new Exception("Attribute Error:Predicate::and");
                 }
-            });
-        }
+            } else {
+                throw new Exception("Attribute Error:Predicate::and");
+            }
+        });
         return true;
     }
 
     /**
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function getAnd(): ?array {
+    public function getAnd(): array {
         if (Predicate::validateAnd($this->and))  {
             return $this->and;
         }
@@ -44180,88 +43982,78 @@ class Predicate {
     }
 
     /**
-     * @return ?array
+     * @return array
      */
-    public static function sampleAnd(): ?array {
+    public static function sampleAnd(): array {
         return  array(
             Predicate::sample() /*32:*/
         ); /* 32:and*/
     }
 
     /**
-     * @param ?array $value
+     * @param array $value
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public static function fromOr(?array $value): ?array {
-        if (!is_null($value)) {
-            return  array_map(function ($value) {
-                if (is_object($value)) {
-                    return Predicate::from($value); /*class*/
-                } elseif (is_string($value)) {
-                    return $value; /*string*/
-                } else {
-                    throw new Exception('Cannot deserialize union value in Predicate');
-                }
-            }, $value);
-        } else {
-            return  null;
-        }
+    public static function fromOr(array $value): array {
+        return  array_map(function ($value) {
+            if (is_object($value)) {
+                return Predicate::from($value); /*class*/
+            } elseif (is_string($value)) {
+                return $value; /*string*/
+            } else {
+                throw new Exception('Cannot deserialize union value in Predicate');
+            }
+        }, $value);
     }
 
     /**
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function toOr(): ?array {
+    public function toOr(): array {
         if (Predicate::validateOr($this->or))  {
-            if (!is_null($this->or)) {
-                return array_map(function ($value) {
-                    if ($value instanceof Predicate) {
-                        return $value->to(); /*class*/
-                    } elseif (is_string($value)) {
-                        return $value; /*string*/
-                    } else {
-                        throw new Exception('Union value has no matching member in Predicate');
-                    }
-                }, $this->or);
-            } else {
-                return  null;
-            }
+            return array_map(function ($value) {
+                if ($value instanceof Predicate) {
+                    return $value->to(); /*class*/
+                } elseif (is_string($value)) {
+                    return $value; /*string*/
+                } else {
+                    throw new Exception('Union value has no matching member in Predicate');
+                }
+            }, $this->or);
         }
         throw new Exception('never get to this Predicate::or');
     }
 
     /**
-     * @param array|null
+     * @param array
      * @return bool
      * @throws Exception
      */
-    public static function validateOr(?array $value): bool {
-        if (!is_null($value)) {
-            if (!is_array($value)) {
-                throw new Exception("Attribute Error:Predicate::or");
-            }
-            array_walk($value, function($value_v) {
-                if ($value_v instanceof Predicate) {
-                    $value_v->validate();
-                } elseif (is_string($value_v)) {
-                    if (!is_string($value_v)) {
-                        throw new Exception("Attribute Error:Predicate::or");
-                    }
-                } else {
+    public static function validateOr(array $value): bool {
+        if (!is_array($value)) {
+            throw new Exception("Attribute Error:Predicate::or");
+        }
+        array_walk($value, function($value_v) {
+            if ($value_v instanceof Predicate) {
+                $value_v->validate();
+            } elseif (is_string($value_v)) {
+                if (!is_string($value_v)) {
                     throw new Exception("Attribute Error:Predicate::or");
                 }
-            });
-        }
+            } else {
+                throw new Exception("Attribute Error:Predicate::or");
+            }
+        });
         return true;
     }
 
     /**
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function getOr(): ?array {
+    public function getOr(): array {
         if (Predicate::validateOr($this->or))  {
             return $this->or;
         }
@@ -44269,9 +44061,9 @@ class Predicate {
     }
 
     /**
-     * @return ?array
+     * @return array
      */
-    public static function sampleOr(): ?array {
+    public static function sampleOr(): array {
         return  array(
             Predicate::sample() /*33:*/
         ); /* 33:or*/
@@ -44280,14 +44072,12 @@ class Predicate {
     /**
      * The value that the field should be equal to.
      *
-     * @param stdClass|bool|float|string|null $value
+     * @param stdClass|bool|float|string $value
      * @throws Exception
-     * @return DateTimeClass|bool|float|string|null
+     * @return DateTimeClass|bool|float|string
      */
-    public static function fromEqual(stdClass|bool|float|string|null $value): DateTimeClass|bool|float|string|null {
-        if (is_null($value)) {
-            return $value; /*null*/
-        } elseif (is_object($value)) {
+    public static function fromEqual(stdClass|bool|float|string $value): DateTimeClass|bool|float|string {
+        if (is_object($value)) {
             return DateTimeClass::from($value); /*class*/
         } elseif (is_bool($value)) {
             return $value; /*bool*/
@@ -44304,13 +44094,11 @@ class Predicate {
      * The value that the field should be equal to.
      *
      * @throws Exception
-     * @return stdClass|bool|float|string|null
+     * @return stdClass|bool|float|string
      */
-    public function toEqual(): stdClass|bool|float|string|null {
+    public function toEqual(): stdClass|bool|float|string {
         if (Predicate::validateEqual($this->equal))  {
-            if (is_null($this->equal)) {
-                return $this->equal; /*null*/
-            } elseif ($this->equal instanceof DateTimeClass) {
+            if ($this->equal instanceof DateTimeClass) {
                 return $this->equal->to(); /*class*/
             } elseif (is_bool($this->equal)) {
                 return $this->equal; /*bool*/
@@ -44328,16 +44116,12 @@ class Predicate {
     /**
      * The value that the field should be equal to.
      *
-     * @param DateTimeClass|bool|float|string|null
+     * @param DateTimeClass|bool|float|string
      * @return bool
      * @throws Exception
      */
-    public static function validateEqual(DateTimeClass|bool|float|string|null $value): bool {
-        if (is_null($value)) {
-            if (!is_null($value)) {
-                throw new Exception("Attribute Error:Predicate::equal");
-            }
-        } elseif ($value instanceof DateTimeClass) {
+    public static function validateEqual(DateTimeClass|bool|float|string $value): bool {
+        if ($value instanceof DateTimeClass) {
             $value->validate();
         } elseif (is_bool($value)) {
             if (!is_bool($value)) {
@@ -44361,9 +44145,9 @@ class Predicate {
      * The value that the field should be equal to.
      *
      * @throws Exception
-     * @return DateTimeClass|bool|float|string|null
+     * @return DateTimeClass|bool|float|string
      */
-    public function getEqual(): DateTimeClass|bool|float|string|null {
+    public function getEqual(): DateTimeClass|bool|float|string {
         if (Predicate::validateEqual($this->equal))  {
             return $this->equal;
         }
@@ -44373,9 +44157,9 @@ class Predicate {
     /**
      * The value that the field should be equal to.
      *
-     * @return DateTimeClass|bool|float|string|null
+     * @return DateTimeClass|bool|float|string
      */
-    public static function sampleEqual(): DateTimeClass|bool|float|string|null {
+    public static function sampleEqual(): DateTimeClass|bool|float|string {
         return DateTimeClass::sample(); /*34:equal*/
     }
 
@@ -44384,16 +44168,12 @@ class Predicate {
      *
      * Field to be filtered
      *
-     * @param ?string $value
+     * @param string $value
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public static function fromField(?string $value): ?string {
-        if (!is_null($value)) {
-            return $value; /*string*/
-        } else {
-            return  null;
-        }
+    public static function fromField(string $value): string {
+        return $value; /*string*/
     }
 
     /**
@@ -44402,15 +44182,11 @@ class Predicate {
      * Field to be filtered
      *
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public function toField(): ?string {
+    public function toField(): string {
         if (Predicate::validateField($this->field))  {
-            if (!is_null($this->field)) {
-                return $this->field; /*string*/
-            } else {
-                return  null;
-            }
+            return $this->field; /*string*/
         }
         throw new Exception('never get to this Predicate::field');
     }
@@ -44420,13 +44196,11 @@ class Predicate {
      *
      * Field to be filtered
      *
-     * @param string|null
+     * @param string
      * @return bool
      * @throws Exception
      */
-    public static function validateField(?string $value): bool {
-        if (!is_null($value)) {
-        }
+    public static function validateField(string $value): bool {
         return true;
     }
 
@@ -44436,9 +44210,9 @@ class Predicate {
      * Field to be filtered
      *
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public function getField(): ?string {
+    public function getField(): string {
         if (Predicate::validateField($this->field))  {
             return $this->field;
         }
@@ -44450,9 +44224,9 @@ class Predicate {
      *
      * Field to be filtered
      *
-     * @return ?string
+     * @return string
      */
-    public static function sampleField(): ?string {
+    public static function sampleField(): string {
         return 'Predicate::field::35'; /*35:field*/
     }
 
@@ -44538,26 +44312,22 @@ class Predicate {
      * An array of inclusive minimum and maximum values
      * for a field value of a data item to be included in the filtered data.
      *
-     * @param ?array $value
+     * @param array $value
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public static function fromRange(?array $value): ?array {
-        if (!is_null($value)) {
-            return  array_map(function ($value) {
-                if (is_null($value)) {
-                    return $value; /*null*/
-                } elseif (is_object($value)) {
-                    return DateTimeClass::from($value); /*class*/
-                } elseif (is_float($value) || is_int($value)) {
-                    return $value; /*float*/
-                } else {
-                    throw new Exception('Cannot deserialize union value in Predicate');
-                }
-            }, $value);
-        } else {
-            return  null;
-        }
+    public static function fromRange(array $value): array {
+        return  array_map(function ($value) {
+            if (is_null($value)) {
+                return $value; /*null*/
+            } elseif (is_object($value)) {
+                return DateTimeClass::from($value); /*class*/
+            } elseif (is_float($value) || is_int($value)) {
+                return $value; /*float*/
+            } else {
+                throw new Exception('Cannot deserialize union value in Predicate');
+            }
+        }, $value);
     }
 
     /**
@@ -44565,25 +44335,21 @@ class Predicate {
      * for a field value of a data item to be included in the filtered data.
      *
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function toRange(): ?array {
+    public function toRange(): array {
         if (Predicate::validateRange($this->range))  {
-            if (!is_null($this->range)) {
-                return array_map(function ($value) {
-                    if (is_null($value)) {
-                        return $value; /*null*/
-                    } elseif ($value instanceof DateTimeClass) {
-                        return $value->to(); /*class*/
-                    } elseif (is_float($value) || is_int($value)) {
-                        return $value; /*float*/
-                    } else {
-                        throw new Exception('Union value has no matching member in Predicate');
-                    }
-                }, $this->range);
-            } else {
-                return  null;
-            }
+            return array_map(function ($value) {
+                if (is_null($value)) {
+                    return $value; /*null*/
+                } elseif ($value instanceof DateTimeClass) {
+                    return $value->to(); /*class*/
+                } elseif (is_float($value) || is_int($value)) {
+                    return $value; /*float*/
+                } else {
+                    throw new Exception('Union value has no matching member in Predicate');
+                }
+            }, $this->range);
         }
         throw new Exception('never get to this Predicate::range');
     }
@@ -44592,31 +44358,29 @@ class Predicate {
      * An array of inclusive minimum and maximum values
      * for a field value of a data item to be included in the filtered data.
      *
-     * @param array|null
+     * @param array
      * @return bool
      * @throws Exception
      */
-    public static function validateRange(?array $value): bool {
-        if (!is_null($value)) {
-            if (!is_array($value)) {
-                throw new Exception("Attribute Error:Predicate::range");
-            }
-            array_walk($value, function($value_v) {
-                if (is_null($value_v)) {
-                    if (!is_null($value_v)) {
-                        throw new Exception("Attribute Error:Predicate::range");
-                    }
-                } elseif ($value_v instanceof DateTimeClass) {
-                    $value_v->validate();
-                } elseif (is_float($value_v) || is_int($value_v)) {
-                    if (!is_float($value_v) && !is_int($value_v)) {
-                        throw new Exception("Attribute Error:Predicate::range");
-                    }
-                } else {
+    public static function validateRange(array $value): bool {
+        if (!is_array($value)) {
+            throw new Exception("Attribute Error:Predicate::range");
+        }
+        array_walk($value, function($value_v) {
+            if (is_null($value_v)) {
+                if (!is_null($value_v)) {
                     throw new Exception("Attribute Error:Predicate::range");
                 }
-            });
-        }
+            } elseif ($value_v instanceof DateTimeClass) {
+                $value_v->validate();
+            } elseif (is_float($value_v) || is_int($value_v)) {
+                if (!is_float($value_v) && !is_int($value_v)) {
+                    throw new Exception("Attribute Error:Predicate::range");
+                }
+            } else {
+                throw new Exception("Attribute Error:Predicate::range");
+            }
+        });
         return true;
     }
 
@@ -44625,9 +44389,9 @@ class Predicate {
      * for a field value of a data item to be included in the filtered data.
      *
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function getRange(): ?array {
+    public function getRange(): array {
         if (Predicate::validateRange($this->range))  {
             return $this->range;
         }
@@ -44638,9 +44402,9 @@ class Predicate {
      * An array of inclusive minimum and maximum values
      * for a field value of a data item to be included in the filtered data.
      *
-     * @return ?array
+     * @return array
      */
-    public static function sampleRange(): ?array {
+    public static function sampleRange(): array {
         return  array(
             DateTimeClass::sample() /*37:*/
         ); /* 37:range*/
@@ -44650,28 +44414,24 @@ class Predicate {
      * A set of values that the `field`'s value should be a member of,
      * for a data item included in the filtered data.
      *
-     * @param ?array $value
+     * @param array $value
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public static function fromOneOf(?array $value): ?array {
-        if (!is_null($value)) {
-            return  array_map(function ($value) {
-                if (is_object($value)) {
-                    return DateTimeClass::from($value); /*class*/
-                } elseif (is_bool($value)) {
-                    return $value; /*bool*/
-                } elseif (is_float($value) || is_int($value)) {
-                    return $value; /*float*/
-                } elseif (is_string($value)) {
-                    return $value; /*string*/
-                } else {
-                    throw new Exception('Cannot deserialize union value in Predicate');
-                }
-            }, $value);
-        } else {
-            return  null;
-        }
+    public static function fromOneOf(array $value): array {
+        return  array_map(function ($value) {
+            if (is_object($value)) {
+                return DateTimeClass::from($value); /*class*/
+            } elseif (is_bool($value)) {
+                return $value; /*bool*/
+            } elseif (is_float($value) || is_int($value)) {
+                return $value; /*float*/
+            } elseif (is_string($value)) {
+                return $value; /*string*/
+            } else {
+                throw new Exception('Cannot deserialize union value in Predicate');
+            }
+        }, $value);
     }
 
     /**
@@ -44679,27 +44439,23 @@ class Predicate {
      * for a data item included in the filtered data.
      *
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function toOneOf(): ?array {
+    public function toOneOf(): array {
         if (Predicate::validateOneOf($this->oneOf))  {
-            if (!is_null($this->oneOf)) {
-                return array_map(function ($value) {
-                    if ($value instanceof DateTimeClass) {
-                        return $value->to(); /*class*/
-                    } elseif (is_bool($value)) {
-                        return $value; /*bool*/
-                    } elseif (is_float($value) || is_int($value)) {
-                        return $value; /*float*/
-                    } elseif (is_string($value)) {
-                        return $value; /*string*/
-                    } else {
-                        throw new Exception('Union value has no matching member in Predicate');
-                    }
-                }, $this->oneOf);
-            } else {
-                return  null;
-            }
+            return array_map(function ($value) {
+                if ($value instanceof DateTimeClass) {
+                    return $value->to(); /*class*/
+                } elseif (is_bool($value)) {
+                    return $value; /*bool*/
+                } elseif (is_float($value) || is_int($value)) {
+                    return $value; /*float*/
+                } elseif (is_string($value)) {
+                    return $value; /*string*/
+                } else {
+                    throw new Exception('Union value has no matching member in Predicate');
+                }
+            }, $this->oneOf);
         }
         throw new Exception('never get to this Predicate::oneOf');
     }
@@ -44708,35 +44464,33 @@ class Predicate {
      * A set of values that the `field`'s value should be a member of,
      * for a data item included in the filtered data.
      *
-     * @param array|null
+     * @param array
      * @return bool
      * @throws Exception
      */
-    public static function validateOneOf(?array $value): bool {
-        if (!is_null($value)) {
-            if (!is_array($value)) {
-                throw new Exception("Attribute Error:Predicate::oneOf");
-            }
-            array_walk($value, function($value_v) {
-                if ($value_v instanceof DateTimeClass) {
-                    $value_v->validate();
-                } elseif (is_bool($value_v)) {
-                    if (!is_bool($value_v)) {
-                        throw new Exception("Attribute Error:Predicate::oneOf");
-                    }
-                } elseif (is_float($value_v) || is_int($value_v)) {
-                    if (!is_float($value_v) && !is_int($value_v)) {
-                        throw new Exception("Attribute Error:Predicate::oneOf");
-                    }
-                } elseif (is_string($value_v)) {
-                    if (!is_string($value_v)) {
-                        throw new Exception("Attribute Error:Predicate::oneOf");
-                    }
-                } else {
+    public static function validateOneOf(array $value): bool {
+        if (!is_array($value)) {
+            throw new Exception("Attribute Error:Predicate::oneOf");
+        }
+        array_walk($value, function($value_v) {
+            if ($value_v instanceof DateTimeClass) {
+                $value_v->validate();
+            } elseif (is_bool($value_v)) {
+                if (!is_bool($value_v)) {
                     throw new Exception("Attribute Error:Predicate::oneOf");
                 }
-            });
-        }
+            } elseif (is_float($value_v) || is_int($value_v)) {
+                if (!is_float($value_v) && !is_int($value_v)) {
+                    throw new Exception("Attribute Error:Predicate::oneOf");
+                }
+            } elseif (is_string($value_v)) {
+                if (!is_string($value_v)) {
+                    throw new Exception("Attribute Error:Predicate::oneOf");
+                }
+            } else {
+                throw new Exception("Attribute Error:Predicate::oneOf");
+            }
+        });
         return true;
     }
 
@@ -44745,9 +44499,9 @@ class Predicate {
      * for a data item included in the filtered data.
      *
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function getOneOf(): ?array {
+    public function getOneOf(): array {
         if (Predicate::validateOneOf($this->oneOf))  {
             return $this->oneOf;
         }
@@ -44758,9 +44512,9 @@ class Predicate {
      * A set of values that the `field`'s value should be a member of,
      * for a data item included in the filtered data.
      *
-     * @return ?array
+     * @return array
      */
-    public static function sampleOneOf(): ?array {
+    public static function sampleOneOf(): array {
         return  array(
             DateTimeClass::sample() /*38:*/
         ); /* 38:oneOf*/
@@ -44769,14 +44523,12 @@ class Predicate {
     /**
      * Filter using a selection name.
      *
-     * @param stdClass|string|null $value
+     * @param stdClass|string $value
      * @throws Exception
-     * @return Selection|string|null
+     * @return Selection|string
      */
-    public static function fromSelection(stdClass|string|null $value): Selection|string|null {
-        if (is_null($value)) {
-            return $value; /*null*/
-        } elseif (is_object($value)) {
+    public static function fromSelection(stdClass|string $value): Selection|string {
+        if (is_object($value)) {
             return Selection::from($value); /*class*/
         } elseif (is_string($value)) {
             return $value; /*string*/
@@ -44789,13 +44541,11 @@ class Predicate {
      * Filter using a selection name.
      *
      * @throws Exception
-     * @return stdClass|string|null
+     * @return stdClass|string
      */
-    public function toSelection(): stdClass|string|null {
+    public function toSelection(): stdClass|string {
         if (Predicate::validateSelection($this->selection))  {
-            if (is_null($this->selection)) {
-                return $this->selection; /*null*/
-            } elseif ($this->selection instanceof Selection) {
+            if ($this->selection instanceof Selection) {
                 return $this->selection->to(); /*class*/
             } elseif (is_string($this->selection)) {
                 return $this->selection; /*string*/
@@ -44809,16 +44559,12 @@ class Predicate {
     /**
      * Filter using a selection name.
      *
-     * @param Selection|string|null
+     * @param Selection|string
      * @return bool
      * @throws Exception
      */
-    public static function validateSelection(Selection|string|null $value): bool {
-        if (is_null($value)) {
-            if (!is_null($value)) {
-                throw new Exception("Attribute Error:Predicate::selection");
-            }
-        } elseif ($value instanceof Selection) {
+    public static function validateSelection(Selection|string $value): bool {
+        if ($value instanceof Selection) {
             $value->validate();
         } elseif (is_string($value)) {
             if (!is_string($value)) {
@@ -44834,9 +44580,9 @@ class Predicate {
      * Filter using a selection name.
      *
      * @throws Exception
-     * @return Selection|string|null
+     * @return Selection|string
      */
-    public function getSelection(): Selection|string|null {
+    public function getSelection(): Selection|string {
         if (Predicate::validateSelection($this->selection))  {
             return $this->selection;
         }
@@ -44846,9 +44592,9 @@ class Predicate {
     /**
      * Filter using a selection name.
      *
-     * @return Selection|string|null
+     * @return Selection|string
      */
-    public static function sampleSelection(): Selection|string|null {
+    public static function sampleSelection(): Selection|string {
         return Selection::sample(); /*39:selection*/
     }
 
@@ -46016,9 +45762,9 @@ TimeUnit::init();
 // This is an autogenerated file:ConditionalPredicateMarkPropFieldDefClass
 
 class ConditionalPredicateMarkPropFieldDefClass {
-    private Predicate|string|null $test; // json:test Optional
-    private bool|float|string|null $value; // json:value Optional
-    private Selection|string|null $selection; // json:selection Optional
+    private Predicate|string $test; // json:test Required
+    private bool|float|string $value; // json:value Required
+    private Selection|string $selection; // json:selection Required
     private ?AggregateOp $aggregate; // json:aggregate Optional
     private BinParams|bool|null $bin; // json:bin Optional
     private RepeatRef|string|null $field; // json:field Optional
@@ -46026,12 +45772,12 @@ class ConditionalPredicateMarkPropFieldDefClass {
     private ?Scale $scale; // json:scale Optional
     private SortField|SortOrder|null $sort; // json:sort Optional
     private ?TimeUnit $timeUnit; // json:timeUnit Optional
-    private ?Type $type; // json:type Optional
+    private Type $type; // json:type Required
 
     /**
-     * @param Predicate|string|null $test
-     * @param bool|float|string|null $value
-     * @param Selection|string|null $selection
+     * @param Predicate|string $test
+     * @param bool|float|string $value
+     * @param Selection|string $selection
      * @param AggregateOp|null $aggregate
      * @param BinParams|bool|null $bin
      * @param RepeatRef|string|null $field
@@ -46039,9 +45785,9 @@ class ConditionalPredicateMarkPropFieldDefClass {
      * @param Scale|null $scale
      * @param SortField|SortOrder|null $sort
      * @param TimeUnit|null $timeUnit
-     * @param Type|null $type
+     * @param Type $type
      */
-    public function __construct(Predicate|string|null $test, bool|float|string|null $value, Selection|string|null $selection, ?AggregateOp $aggregate, BinParams|bool|null $bin, RepeatRef|string|null $field, ?Legend $legend, ?Scale $scale, SortField|SortOrder|null $sort, ?TimeUnit $timeUnit, ?Type $type) {
+    public function __construct(Predicate|string $test, bool|float|string $value, Selection|string $selection, ?AggregateOp $aggregate, BinParams|bool|null $bin, RepeatRef|string|null $field, ?Legend $legend, ?Scale $scale, SortField|SortOrder|null $sort, ?TimeUnit $timeUnit, Type $type) {
         $this->test = $test;
         $this->value = $value;
         $this->selection = $selection;
@@ -46056,14 +45802,12 @@ class ConditionalPredicateMarkPropFieldDefClass {
     }
 
     /**
-     * @param stdClass|string|null $value
+     * @param stdClass|string $value
      * @throws Exception
-     * @return Predicate|string|null
+     * @return Predicate|string
      */
-    public static function fromTest(stdClass|string|null $value): Predicate|string|null {
-        if (is_null($value)) {
-            return $value; /*null*/
-        } elseif (is_object($value)) {
+    public static function fromTest(stdClass|string $value): Predicate|string {
+        if (is_object($value)) {
             return Predicate::from($value); /*class*/
         } elseif (is_string($value)) {
             return $value; /*string*/
@@ -46074,13 +45818,11 @@ class ConditionalPredicateMarkPropFieldDefClass {
 
     /**
      * @throws Exception
-     * @return stdClass|string|null
+     * @return stdClass|string
      */
-    public function toTest(): stdClass|string|null {
+    public function toTest(): stdClass|string {
         if (ConditionalPredicateMarkPropFieldDefClass::validateTest($this->test))  {
-            if (is_null($this->test)) {
-                return $this->test; /*null*/
-            } elseif ($this->test instanceof Predicate) {
+            if ($this->test instanceof Predicate) {
                 return $this->test->to(); /*class*/
             } elseif (is_string($this->test)) {
                 return $this->test; /*string*/
@@ -46092,16 +45834,12 @@ class ConditionalPredicateMarkPropFieldDefClass {
     }
 
     /**
-     * @param Predicate|string|null
+     * @param Predicate|string
      * @return bool
      * @throws Exception
      */
-    public static function validateTest(Predicate|string|null $value): bool {
-        if (is_null($value)) {
-            if (!is_null($value)) {
-                throw new Exception("Attribute Error:ConditionalPredicateMarkPropFieldDefClass::test");
-            }
-        } elseif ($value instanceof Predicate) {
+    public static function validateTest(Predicate|string $value): bool {
+        if ($value instanceof Predicate) {
             $value->validate();
         } elseif (is_string($value)) {
             if (!is_string($value)) {
@@ -46115,9 +45853,9 @@ class ConditionalPredicateMarkPropFieldDefClass {
 
     /**
      * @throws Exception
-     * @return Predicate|string|null
+     * @return Predicate|string
      */
-    public function getTest(): Predicate|string|null {
+    public function getTest(): Predicate|string {
         if (ConditionalPredicateMarkPropFieldDefClass::validateTest($this->test))  {
             return $this->test;
         }
@@ -46125,9 +45863,9 @@ class ConditionalPredicateMarkPropFieldDefClass {
     }
 
     /**
-     * @return Predicate|string|null
+     * @return Predicate|string
      */
-    public static function sampleTest(): Predicate|string|null {
+    public static function sampleTest(): Predicate|string {
         return Predicate::sample(); /*31:test*/
     }
 
@@ -46135,14 +45873,12 @@ class ConditionalPredicateMarkPropFieldDefClass {
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      *
-     * @param bool|float|string|null $value
+     * @param bool|float|string $value
      * @throws Exception
-     * @return bool|float|string|null
+     * @return bool|float|string
      */
-    public static function fromValue(bool|float|string|null $value): bool|float|string|null {
-        if (is_null($value)) {
-            return $value; /*null*/
-        } elseif (is_bool($value)) {
+    public static function fromValue(bool|float|string $value): bool|float|string {
+        if (is_bool($value)) {
             return $value; /*bool*/
         } elseif (is_float($value) || is_int($value)) {
             return $value; /*float*/
@@ -46158,13 +45894,11 @@ class ConditionalPredicateMarkPropFieldDefClass {
      * `0` to `1` for opacity).
      *
      * @throws Exception
-     * @return bool|float|string|null
+     * @return bool|float|string
      */
-    public function toValue(): bool|float|string|null {
+    public function toValue(): bool|float|string {
         if (ConditionalPredicateMarkPropFieldDefClass::validateValue($this->value))  {
-            if (is_null($this->value)) {
-                return $this->value; /*null*/
-            } elseif (is_bool($this->value)) {
+            if (is_bool($this->value)) {
                 return $this->value; /*bool*/
             } elseif (is_float($this->value) || is_int($this->value)) {
                 return $this->value; /*float*/
@@ -46181,16 +45915,12 @@ class ConditionalPredicateMarkPropFieldDefClass {
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      *
-     * @param bool|float|string|null
+     * @param bool|float|string
      * @return bool
      * @throws Exception
      */
-    public static function validateValue(bool|float|string|null $value): bool {
-        if (is_null($value)) {
-            if (!is_null($value)) {
-                throw new Exception("Attribute Error:ConditionalPredicateMarkPropFieldDefClass::value");
-            }
-        } elseif (is_bool($value)) {
+    public static function validateValue(bool|float|string $value): bool {
+        if (is_bool($value)) {
             if (!is_bool($value)) {
                 throw new Exception("Attribute Error:ConditionalPredicateMarkPropFieldDefClass::value");
             }
@@ -46213,9 +45943,9 @@ class ConditionalPredicateMarkPropFieldDefClass {
      * `0` to `1` for opacity).
      *
      * @throws Exception
-     * @return bool|float|string|null
+     * @return bool|float|string
      */
-    public function getValue(): bool|float|string|null {
+    public function getValue(): bool|float|string {
         if (ConditionalPredicateMarkPropFieldDefClass::validateValue($this->value))  {
             return $this->value;
         }
@@ -46226,9 +45956,9 @@ class ConditionalPredicateMarkPropFieldDefClass {
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      *
-     * @return bool|float|string|null
+     * @return bool|float|string
      */
-    public static function sampleValue(): bool|float|string|null {
+    public static function sampleValue(): bool|float|string {
         return true; /*32:value*/
     }
 
@@ -46236,14 +45966,12 @@ class ConditionalPredicateMarkPropFieldDefClass {
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      *
-     * @param stdClass|string|null $value
+     * @param stdClass|string $value
      * @throws Exception
-     * @return Selection|string|null
+     * @return Selection|string
      */
-    public static function fromSelection(stdClass|string|null $value): Selection|string|null {
-        if (is_null($value)) {
-            return $value; /*null*/
-        } elseif (is_object($value)) {
+    public static function fromSelection(stdClass|string $value): Selection|string {
+        if (is_object($value)) {
             return Selection::from($value); /*class*/
         } elseif (is_string($value)) {
             return $value; /*string*/
@@ -46257,13 +45985,11 @@ class ConditionalPredicateMarkPropFieldDefClass {
      * selections](selection.html#compose).
      *
      * @throws Exception
-     * @return stdClass|string|null
+     * @return stdClass|string
      */
-    public function toSelection(): stdClass|string|null {
+    public function toSelection(): stdClass|string {
         if (ConditionalPredicateMarkPropFieldDefClass::validateSelection($this->selection))  {
-            if (is_null($this->selection)) {
-                return $this->selection; /*null*/
-            } elseif ($this->selection instanceof Selection) {
+            if ($this->selection instanceof Selection) {
                 return $this->selection->to(); /*class*/
             } elseif (is_string($this->selection)) {
                 return $this->selection; /*string*/
@@ -46278,16 +46004,12 @@ class ConditionalPredicateMarkPropFieldDefClass {
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      *
-     * @param Selection|string|null
+     * @param Selection|string
      * @return bool
      * @throws Exception
      */
-    public static function validateSelection(Selection|string|null $value): bool {
-        if (is_null($value)) {
-            if (!is_null($value)) {
-                throw new Exception("Attribute Error:ConditionalPredicateMarkPropFieldDefClass::selection");
-            }
-        } elseif ($value instanceof Selection) {
+    public static function validateSelection(Selection|string $value): bool {
+        if ($value instanceof Selection) {
             $value->validate();
         } elseif (is_string($value)) {
             if (!is_string($value)) {
@@ -46304,9 +46026,9 @@ class ConditionalPredicateMarkPropFieldDefClass {
      * selections](selection.html#compose).
      *
      * @throws Exception
-     * @return Selection|string|null
+     * @return Selection|string
      */
-    public function getSelection(): Selection|string|null {
+    public function getSelection(): Selection|string {
         if (ConditionalPredicateMarkPropFieldDefClass::validateSelection($this->selection))  {
             return $this->selection;
         }
@@ -46317,9 +46039,9 @@ class ConditionalPredicateMarkPropFieldDefClass {
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      *
-     * @return Selection|string|null
+     * @return Selection|string
      */
-    public static function sampleSelection(): Selection|string|null {
+    public static function sampleSelection(): Selection|string {
         return Selection::sample(); /*33:selection*/
     }
 
@@ -47012,16 +46734,12 @@ class ConditionalPredicateMarkPropFieldDefClass {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      *
-     * @param ?string $value
+     * @param string $value
      * @throws Exception
-     * @return ?Type
+     * @return Type
      */
-    public static function fromType(?string $value): ?Type {
-        if (!is_null($value)) {
-            return Type::from($value); /*enum*/
-        } else {
-            return  null;
-        }
+    public static function fromType(string $value): Type {
+        return Type::from($value); /*enum*/
     }
 
     /**
@@ -47031,15 +46749,11 @@ class ConditionalPredicateMarkPropFieldDefClass {
      * [geographic projection](projection.html) is applied.
      *
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public function toType(): ?string {
+    public function toType(): string {
         if (ConditionalPredicateMarkPropFieldDefClass::validateType($this->type))  {
-            if (!is_null($this->type)) {
-                return Type::to($this->type); /*enum*/
-            } else {
-                return  null;
-            }
+            return Type::to($this->type); /*enum*/
         }
         throw new Exception('never get to this ConditionalPredicateMarkPropFieldDefClass::type');
     }
@@ -47050,14 +46764,12 @@ class ConditionalPredicateMarkPropFieldDefClass {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      *
-     * @param Type|null
+     * @param Type
      * @return bool
      * @throws Exception
      */
-    public static function validateType(?Type $value): bool {
-        if (!is_null($value)) {
-            Type::to($value);
-        }
+    public static function validateType(Type $value): bool {
+        Type::to($value);
         return true;
     }
 
@@ -47068,9 +46780,9 @@ class ConditionalPredicateMarkPropFieldDefClass {
      * [geographic projection](projection.html) is applied.
      *
      * @throws Exception
-     * @return ?Type
+     * @return Type
      */
-    public function getType(): ?Type {
+    public function getType(): Type {
         if (ConditionalPredicateMarkPropFieldDefClass::validateType($this->type))  {
             return $this->type;
         }
@@ -47083,9 +46795,9 @@ class ConditionalPredicateMarkPropFieldDefClass {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      *
-     * @return ?Type
+     * @return Type
      */
-    public static function sampleType(): ?Type {
+    public static function sampleType(): Type {
         return Type::sample(); /*enum*/
     }
 
@@ -53576,7 +53288,7 @@ class DefWithCondition {
     private ConditionalPredicateFieldDefClass|array|null $condition; // json:condition Optional
     private RepeatRef|string|null $field; // json:field Optional
     private ?TimeUnit $timeUnit; // json:timeUnit Optional
-    private ?Type $type; // json:type Optional
+    private Type $type; // json:type Required
     private bool|float|string|null $value; // json:value Optional
 
     /**
@@ -53585,10 +53297,10 @@ class DefWithCondition {
      * @param ConditionalPredicateFieldDefClass|array|null $condition
      * @param RepeatRef|string|null $field
      * @param TimeUnit|null $timeUnit
-     * @param Type|null $type
+     * @param Type $type
      * @param bool|float|string|null $value
      */
-    public function __construct(?AggregateOp $aggregate, BinParams|bool|null $bin, ConditionalPredicateFieldDefClass|array|null $condition, RepeatRef|string|null $field, ?TimeUnit $timeUnit, ?Type $type, bool|float|string|null $value) {
+    public function __construct(?AggregateOp $aggregate, BinParams|bool|null $bin, ConditionalPredicateFieldDefClass|array|null $condition, RepeatRef|string|null $field, ?TimeUnit $timeUnit, Type $type, bool|float|string|null $value) {
         $this->aggregate = $aggregate;
         $this->bin = $bin;
         $this->condition = $condition;
@@ -54130,16 +53842,12 @@ class DefWithCondition {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      *
-     * @param ?string $value
+     * @param string $value
      * @throws Exception
-     * @return ?Type
+     * @return Type
      */
-    public static function fromType(?string $value): ?Type {
-        if (!is_null($value)) {
-            return Type::from($value); /*enum*/
-        } else {
-            return  null;
-        }
+    public static function fromType(string $value): Type {
+        return Type::from($value); /*enum*/
     }
 
     /**
@@ -54149,15 +53857,11 @@ class DefWithCondition {
      * [geographic projection](projection.html) is applied.
      *
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public function toType(): ?string {
+    public function toType(): string {
         if (DefWithCondition::validateType($this->type))  {
-            if (!is_null($this->type)) {
-                return Type::to($this->type); /*enum*/
-            } else {
-                return  null;
-            }
+            return Type::to($this->type); /*enum*/
         }
         throw new Exception('never get to this DefWithCondition::type');
     }
@@ -54168,14 +53872,12 @@ class DefWithCondition {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      *
-     * @param Type|null
+     * @param Type
      * @return bool
      * @throws Exception
      */
-    public static function validateType(?Type $value): bool {
-        if (!is_null($value)) {
-            Type::to($value);
-        }
+    public static function validateType(Type $value): bool {
+        Type::to($value);
         return true;
     }
 
@@ -54186,9 +53888,9 @@ class DefWithCondition {
      * [geographic projection](projection.html) is applied.
      *
      * @throws Exception
-     * @return ?Type
+     * @return Type
      */
-    public function getType(): ?Type {
+    public function getType(): Type {
         if (DefWithCondition::validateType($this->type))  {
             return $this->type;
         }
@@ -54201,9 +53903,9 @@ class DefWithCondition {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      *
-     * @return ?Type
+     * @return Type
      */
-    public static function sampleType(): ?Type {
+    public static function sampleType(): Type {
         return Type::sample(); /*enum*/
     }
 
@@ -54369,26 +54071,26 @@ class DefWithCondition {
 // This is an autogenerated file:ConditionalPredicateFieldDefClass
 
 class ConditionalPredicateFieldDefClass {
-    private Predicate|string|null $test; // json:test Optional
-    private bool|float|string|null $value; // json:value Optional
-    private Selection|string|null $selection; // json:selection Optional
+    private Predicate|string $test; // json:test Required
+    private bool|float|string $value; // json:value Required
+    private Selection|string $selection; // json:selection Required
     private ?AggregateOp $aggregate; // json:aggregate Optional
     private BinParams|bool|null $bin; // json:bin Optional
     private RepeatRef|string|null $field; // json:field Optional
     private ?TimeUnit $timeUnit; // json:timeUnit Optional
-    private ?Type $type; // json:type Optional
+    private Type $type; // json:type Required
 
     /**
-     * @param Predicate|string|null $test
-     * @param bool|float|string|null $value
-     * @param Selection|string|null $selection
+     * @param Predicate|string $test
+     * @param bool|float|string $value
+     * @param Selection|string $selection
      * @param AggregateOp|null $aggregate
      * @param BinParams|bool|null $bin
      * @param RepeatRef|string|null $field
      * @param TimeUnit|null $timeUnit
-     * @param Type|null $type
+     * @param Type $type
      */
-    public function __construct(Predicate|string|null $test, bool|float|string|null $value, Selection|string|null $selection, ?AggregateOp $aggregate, BinParams|bool|null $bin, RepeatRef|string|null $field, ?TimeUnit $timeUnit, ?Type $type) {
+    public function __construct(Predicate|string $test, bool|float|string $value, Selection|string $selection, ?AggregateOp $aggregate, BinParams|bool|null $bin, RepeatRef|string|null $field, ?TimeUnit $timeUnit, Type $type) {
         $this->test = $test;
         $this->value = $value;
         $this->selection = $selection;
@@ -54400,14 +54102,12 @@ class ConditionalPredicateFieldDefClass {
     }
 
     /**
-     * @param stdClass|string|null $value
+     * @param stdClass|string $value
      * @throws Exception
-     * @return Predicate|string|null
+     * @return Predicate|string
      */
-    public static function fromTest(stdClass|string|null $value): Predicate|string|null {
-        if (is_null($value)) {
-            return $value; /*null*/
-        } elseif (is_object($value)) {
+    public static function fromTest(stdClass|string $value): Predicate|string {
+        if (is_object($value)) {
             return Predicate::from($value); /*class*/
         } elseif (is_string($value)) {
             return $value; /*string*/
@@ -54418,13 +54118,11 @@ class ConditionalPredicateFieldDefClass {
 
     /**
      * @throws Exception
-     * @return stdClass|string|null
+     * @return stdClass|string
      */
-    public function toTest(): stdClass|string|null {
+    public function toTest(): stdClass|string {
         if (ConditionalPredicateFieldDefClass::validateTest($this->test))  {
-            if (is_null($this->test)) {
-                return $this->test; /*null*/
-            } elseif ($this->test instanceof Predicate) {
+            if ($this->test instanceof Predicate) {
                 return $this->test->to(); /*class*/
             } elseif (is_string($this->test)) {
                 return $this->test; /*string*/
@@ -54436,16 +54134,12 @@ class ConditionalPredicateFieldDefClass {
     }
 
     /**
-     * @param Predicate|string|null
+     * @param Predicate|string
      * @return bool
      * @throws Exception
      */
-    public static function validateTest(Predicate|string|null $value): bool {
-        if (is_null($value)) {
-            if (!is_null($value)) {
-                throw new Exception("Attribute Error:ConditionalPredicateFieldDefClass::test");
-            }
-        } elseif ($value instanceof Predicate) {
+    public static function validateTest(Predicate|string $value): bool {
+        if ($value instanceof Predicate) {
             $value->validate();
         } elseif (is_string($value)) {
             if (!is_string($value)) {
@@ -54459,9 +54153,9 @@ class ConditionalPredicateFieldDefClass {
 
     /**
      * @throws Exception
-     * @return Predicate|string|null
+     * @return Predicate|string
      */
-    public function getTest(): Predicate|string|null {
+    public function getTest(): Predicate|string {
         if (ConditionalPredicateFieldDefClass::validateTest($this->test))  {
             return $this->test;
         }
@@ -54469,9 +54163,9 @@ class ConditionalPredicateFieldDefClass {
     }
 
     /**
-     * @return Predicate|string|null
+     * @return Predicate|string
      */
-    public static function sampleTest(): Predicate|string|null {
+    public static function sampleTest(): Predicate|string {
         return Predicate::sample(); /*31:test*/
     }
 
@@ -54479,14 +54173,12 @@ class ConditionalPredicateFieldDefClass {
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      *
-     * @param bool|float|string|null $value
+     * @param bool|float|string $value
      * @throws Exception
-     * @return bool|float|string|null
+     * @return bool|float|string
      */
-    public static function fromValue(bool|float|string|null $value): bool|float|string|null {
-        if (is_null($value)) {
-            return $value; /*null*/
-        } elseif (is_bool($value)) {
+    public static function fromValue(bool|float|string $value): bool|float|string {
+        if (is_bool($value)) {
             return $value; /*bool*/
         } elseif (is_float($value) || is_int($value)) {
             return $value; /*float*/
@@ -54502,13 +54194,11 @@ class ConditionalPredicateFieldDefClass {
      * `0` to `1` for opacity).
      *
      * @throws Exception
-     * @return bool|float|string|null
+     * @return bool|float|string
      */
-    public function toValue(): bool|float|string|null {
+    public function toValue(): bool|float|string {
         if (ConditionalPredicateFieldDefClass::validateValue($this->value))  {
-            if (is_null($this->value)) {
-                return $this->value; /*null*/
-            } elseif (is_bool($this->value)) {
+            if (is_bool($this->value)) {
                 return $this->value; /*bool*/
             } elseif (is_float($this->value) || is_int($this->value)) {
                 return $this->value; /*float*/
@@ -54525,16 +54215,12 @@ class ConditionalPredicateFieldDefClass {
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      *
-     * @param bool|float|string|null
+     * @param bool|float|string
      * @return bool
      * @throws Exception
      */
-    public static function validateValue(bool|float|string|null $value): bool {
-        if (is_null($value)) {
-            if (!is_null($value)) {
-                throw new Exception("Attribute Error:ConditionalPredicateFieldDefClass::value");
-            }
-        } elseif (is_bool($value)) {
+    public static function validateValue(bool|float|string $value): bool {
+        if (is_bool($value)) {
             if (!is_bool($value)) {
                 throw new Exception("Attribute Error:ConditionalPredicateFieldDefClass::value");
             }
@@ -54557,9 +54243,9 @@ class ConditionalPredicateFieldDefClass {
      * `0` to `1` for opacity).
      *
      * @throws Exception
-     * @return bool|float|string|null
+     * @return bool|float|string
      */
-    public function getValue(): bool|float|string|null {
+    public function getValue(): bool|float|string {
         if (ConditionalPredicateFieldDefClass::validateValue($this->value))  {
             return $this->value;
         }
@@ -54570,9 +54256,9 @@ class ConditionalPredicateFieldDefClass {
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      *
-     * @return bool|float|string|null
+     * @return bool|float|string
      */
-    public static function sampleValue(): bool|float|string|null {
+    public static function sampleValue(): bool|float|string {
         return true; /*32:value*/
     }
 
@@ -54580,14 +54266,12 @@ class ConditionalPredicateFieldDefClass {
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      *
-     * @param stdClass|string|null $value
+     * @param stdClass|string $value
      * @throws Exception
-     * @return Selection|string|null
+     * @return Selection|string
      */
-    public static function fromSelection(stdClass|string|null $value): Selection|string|null {
-        if (is_null($value)) {
-            return $value; /*null*/
-        } elseif (is_object($value)) {
+    public static function fromSelection(stdClass|string $value): Selection|string {
+        if (is_object($value)) {
             return Selection::from($value); /*class*/
         } elseif (is_string($value)) {
             return $value; /*string*/
@@ -54601,13 +54285,11 @@ class ConditionalPredicateFieldDefClass {
      * selections](selection.html#compose).
      *
      * @throws Exception
-     * @return stdClass|string|null
+     * @return stdClass|string
      */
-    public function toSelection(): stdClass|string|null {
+    public function toSelection(): stdClass|string {
         if (ConditionalPredicateFieldDefClass::validateSelection($this->selection))  {
-            if (is_null($this->selection)) {
-                return $this->selection; /*null*/
-            } elseif ($this->selection instanceof Selection) {
+            if ($this->selection instanceof Selection) {
                 return $this->selection->to(); /*class*/
             } elseif (is_string($this->selection)) {
                 return $this->selection; /*string*/
@@ -54622,16 +54304,12 @@ class ConditionalPredicateFieldDefClass {
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      *
-     * @param Selection|string|null
+     * @param Selection|string
      * @return bool
      * @throws Exception
      */
-    public static function validateSelection(Selection|string|null $value): bool {
-        if (is_null($value)) {
-            if (!is_null($value)) {
-                throw new Exception("Attribute Error:ConditionalPredicateFieldDefClass::selection");
-            }
-        } elseif ($value instanceof Selection) {
+    public static function validateSelection(Selection|string $value): bool {
+        if ($value instanceof Selection) {
             $value->validate();
         } elseif (is_string($value)) {
             if (!is_string($value)) {
@@ -54648,9 +54326,9 @@ class ConditionalPredicateFieldDefClass {
      * selections](selection.html#compose).
      *
      * @throws Exception
-     * @return Selection|string|null
+     * @return Selection|string
      */
-    public function getSelection(): Selection|string|null {
+    public function getSelection(): Selection|string {
         if (ConditionalPredicateFieldDefClass::validateSelection($this->selection))  {
             return $this->selection;
         }
@@ -54661,9 +54339,9 @@ class ConditionalPredicateFieldDefClass {
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      *
-     * @return Selection|string|null
+     * @return Selection|string
      */
-    public static function sampleSelection(): Selection|string|null {
+    public static function sampleSelection(): Selection|string {
         return Selection::sample(); /*33:selection*/
     }
 
@@ -55076,16 +54754,12 @@ class ConditionalPredicateFieldDefClass {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      *
-     * @param ?string $value
+     * @param string $value
      * @throws Exception
-     * @return ?Type
+     * @return Type
      */
-    public static function fromType(?string $value): ?Type {
-        if (!is_null($value)) {
-            return Type::from($value); /*enum*/
-        } else {
-            return  null;
-        }
+    public static function fromType(string $value): Type {
+        return Type::from($value); /*enum*/
     }
 
     /**
@@ -55095,15 +54769,11 @@ class ConditionalPredicateFieldDefClass {
      * [geographic projection](projection.html) is applied.
      *
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public function toType(): ?string {
+    public function toType(): string {
         if (ConditionalPredicateFieldDefClass::validateType($this->type))  {
-            if (!is_null($this->type)) {
-                return Type::to($this->type); /*enum*/
-            } else {
-                return  null;
-            }
+            return Type::to($this->type); /*enum*/
         }
         throw new Exception('never get to this ConditionalPredicateFieldDefClass::type');
     }
@@ -55114,14 +54784,12 @@ class ConditionalPredicateFieldDefClass {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      *
-     * @param Type|null
+     * @param Type
      * @return bool
      * @throws Exception
      */
-    public static function validateType(?Type $value): bool {
-        if (!is_null($value)) {
-            Type::to($value);
-        }
+    public static function validateType(Type $value): bool {
+        Type::to($value);
         return true;
     }
 
@@ -55132,9 +54800,9 @@ class ConditionalPredicateFieldDefClass {
      * [geographic projection](projection.html) is applied.
      *
      * @throws Exception
-     * @return ?Type
+     * @return Type
      */
-    public function getType(): ?Type {
+    public function getType(): Type {
         if (ConditionalPredicateFieldDefClass::validateType($this->type))  {
             return $this->type;
         }
@@ -55147,9 +54815,9 @@ class ConditionalPredicateFieldDefClass {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      *
-     * @return ?Type
+     * @return Type
      */
-    public static function sampleType(): ?Type {
+    public static function sampleType(): Type {
         return Type::sample(); /*enum*/
     }
 
@@ -55859,7 +55527,7 @@ class TextDefWithCondition {
     private RepeatRef|string|null $field; // json:field Optional
     private ?string $format; // json:format Optional
     private ?TimeUnit $timeUnit; // json:timeUnit Optional
-    private ?Type $type; // json:type Optional
+    private Type $type; // json:type Required
     private bool|float|string|null $value; // json:value Optional
 
     /**
@@ -55869,10 +55537,10 @@ class TextDefWithCondition {
      * @param RepeatRef|string|null $field
      * @param string|null $format
      * @param TimeUnit|null $timeUnit
-     * @param Type|null $type
+     * @param Type $type
      * @param bool|float|string|null $value
      */
-    public function __construct(?AggregateOp $aggregate, BinParams|bool|null $bin, ConditionalPredicateTextFieldDefClass|array|null $condition, RepeatRef|string|null $field, ?string $format, ?TimeUnit $timeUnit, ?Type $type, bool|float|string|null $value) {
+    public function __construct(?AggregateOp $aggregate, BinParams|bool|null $bin, ConditionalPredicateTextFieldDefClass|array|null $condition, RepeatRef|string|null $field, ?string $format, ?TimeUnit $timeUnit, Type $type, bool|float|string|null $value) {
         $this->aggregate = $aggregate;
         $this->bin = $bin;
         $this->condition = $condition;
@@ -56487,16 +56155,12 @@ class TextDefWithCondition {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      *
-     * @param ?string $value
+     * @param string $value
      * @throws Exception
-     * @return ?Type
+     * @return Type
      */
-    public static function fromType(?string $value): ?Type {
-        if (!is_null($value)) {
-            return Type::from($value); /*enum*/
-        } else {
-            return  null;
-        }
+    public static function fromType(string $value): Type {
+        return Type::from($value); /*enum*/
     }
 
     /**
@@ -56506,15 +56170,11 @@ class TextDefWithCondition {
      * [geographic projection](projection.html) is applied.
      *
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public function toType(): ?string {
+    public function toType(): string {
         if (TextDefWithCondition::validateType($this->type))  {
-            if (!is_null($this->type)) {
-                return Type::to($this->type); /*enum*/
-            } else {
-                return  null;
-            }
+            return Type::to($this->type); /*enum*/
         }
         throw new Exception('never get to this TextDefWithCondition::type');
     }
@@ -56525,14 +56185,12 @@ class TextDefWithCondition {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      *
-     * @param Type|null
+     * @param Type
      * @return bool
      * @throws Exception
      */
-    public static function validateType(?Type $value): bool {
-        if (!is_null($value)) {
-            Type::to($value);
-        }
+    public static function validateType(Type $value): bool {
+        Type::to($value);
         return true;
     }
 
@@ -56543,9 +56201,9 @@ class TextDefWithCondition {
      * [geographic projection](projection.html) is applied.
      *
      * @throws Exception
-     * @return ?Type
+     * @return Type
      */
-    public function getType(): ?Type {
+    public function getType(): Type {
         if (TextDefWithCondition::validateType($this->type))  {
             return $this->type;
         }
@@ -56558,9 +56216,9 @@ class TextDefWithCondition {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      *
-     * @return ?Type
+     * @return Type
      */
-    public static function sampleType(): ?Type {
+    public static function sampleType(): Type {
         return Type::sample(); /*enum*/
     }
 
@@ -56730,28 +56388,28 @@ class TextDefWithCondition {
 // This is an autogenerated file:ConditionalPredicateTextFieldDefClass
 
 class ConditionalPredicateTextFieldDefClass {
-    private Predicate|string|null $test; // json:test Optional
-    private bool|float|string|null $value; // json:value Optional
-    private Selection|string|null $selection; // json:selection Optional
+    private Predicate|string $test; // json:test Required
+    private bool|float|string $value; // json:value Required
+    private Selection|string $selection; // json:selection Required
     private ?AggregateOp $aggregate; // json:aggregate Optional
     private BinParams|bool|null $bin; // json:bin Optional
     private RepeatRef|string|null $field; // json:field Optional
     private ?string $format; // json:format Optional
     private ?TimeUnit $timeUnit; // json:timeUnit Optional
-    private ?Type $type; // json:type Optional
+    private Type $type; // json:type Required
 
     /**
-     * @param Predicate|string|null $test
-     * @param bool|float|string|null $value
-     * @param Selection|string|null $selection
+     * @param Predicate|string $test
+     * @param bool|float|string $value
+     * @param Selection|string $selection
      * @param AggregateOp|null $aggregate
      * @param BinParams|bool|null $bin
      * @param RepeatRef|string|null $field
      * @param string|null $format
      * @param TimeUnit|null $timeUnit
-     * @param Type|null $type
+     * @param Type $type
      */
-    public function __construct(Predicate|string|null $test, bool|float|string|null $value, Selection|string|null $selection, ?AggregateOp $aggregate, BinParams|bool|null $bin, RepeatRef|string|null $field, ?string $format, ?TimeUnit $timeUnit, ?Type $type) {
+    public function __construct(Predicate|string $test, bool|float|string $value, Selection|string $selection, ?AggregateOp $aggregate, BinParams|bool|null $bin, RepeatRef|string|null $field, ?string $format, ?TimeUnit $timeUnit, Type $type) {
         $this->test = $test;
         $this->value = $value;
         $this->selection = $selection;
@@ -56764,14 +56422,12 @@ class ConditionalPredicateTextFieldDefClass {
     }
 
     /**
-     * @param stdClass|string|null $value
+     * @param stdClass|string $value
      * @throws Exception
-     * @return Predicate|string|null
+     * @return Predicate|string
      */
-    public static function fromTest(stdClass|string|null $value): Predicate|string|null {
-        if (is_null($value)) {
-            return $value; /*null*/
-        } elseif (is_object($value)) {
+    public static function fromTest(stdClass|string $value): Predicate|string {
+        if (is_object($value)) {
             return Predicate::from($value); /*class*/
         } elseif (is_string($value)) {
             return $value; /*string*/
@@ -56782,13 +56438,11 @@ class ConditionalPredicateTextFieldDefClass {
 
     /**
      * @throws Exception
-     * @return stdClass|string|null
+     * @return stdClass|string
      */
-    public function toTest(): stdClass|string|null {
+    public function toTest(): stdClass|string {
         if (ConditionalPredicateTextFieldDefClass::validateTest($this->test))  {
-            if (is_null($this->test)) {
-                return $this->test; /*null*/
-            } elseif ($this->test instanceof Predicate) {
+            if ($this->test instanceof Predicate) {
                 return $this->test->to(); /*class*/
             } elseif (is_string($this->test)) {
                 return $this->test; /*string*/
@@ -56800,16 +56454,12 @@ class ConditionalPredicateTextFieldDefClass {
     }
 
     /**
-     * @param Predicate|string|null
+     * @param Predicate|string
      * @return bool
      * @throws Exception
      */
-    public static function validateTest(Predicate|string|null $value): bool {
-        if (is_null($value)) {
-            if (!is_null($value)) {
-                throw new Exception("Attribute Error:ConditionalPredicateTextFieldDefClass::test");
-            }
-        } elseif ($value instanceof Predicate) {
+    public static function validateTest(Predicate|string $value): bool {
+        if ($value instanceof Predicate) {
             $value->validate();
         } elseif (is_string($value)) {
             if (!is_string($value)) {
@@ -56823,9 +56473,9 @@ class ConditionalPredicateTextFieldDefClass {
 
     /**
      * @throws Exception
-     * @return Predicate|string|null
+     * @return Predicate|string
      */
-    public function getTest(): Predicate|string|null {
+    public function getTest(): Predicate|string {
         if (ConditionalPredicateTextFieldDefClass::validateTest($this->test))  {
             return $this->test;
         }
@@ -56833,9 +56483,9 @@ class ConditionalPredicateTextFieldDefClass {
     }
 
     /**
-     * @return Predicate|string|null
+     * @return Predicate|string
      */
-    public static function sampleTest(): Predicate|string|null {
+    public static function sampleTest(): Predicate|string {
         return Predicate::sample(); /*31:test*/
     }
 
@@ -56843,14 +56493,12 @@ class ConditionalPredicateTextFieldDefClass {
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      *
-     * @param bool|float|string|null $value
+     * @param bool|float|string $value
      * @throws Exception
-     * @return bool|float|string|null
+     * @return bool|float|string
      */
-    public static function fromValue(bool|float|string|null $value): bool|float|string|null {
-        if (is_null($value)) {
-            return $value; /*null*/
-        } elseif (is_bool($value)) {
+    public static function fromValue(bool|float|string $value): bool|float|string {
+        if (is_bool($value)) {
             return $value; /*bool*/
         } elseif (is_float($value) || is_int($value)) {
             return $value; /*float*/
@@ -56866,13 +56514,11 @@ class ConditionalPredicateTextFieldDefClass {
      * `0` to `1` for opacity).
      *
      * @throws Exception
-     * @return bool|float|string|null
+     * @return bool|float|string
      */
-    public function toValue(): bool|float|string|null {
+    public function toValue(): bool|float|string {
         if (ConditionalPredicateTextFieldDefClass::validateValue($this->value))  {
-            if (is_null($this->value)) {
-                return $this->value; /*null*/
-            } elseif (is_bool($this->value)) {
+            if (is_bool($this->value)) {
                 return $this->value; /*bool*/
             } elseif (is_float($this->value) || is_int($this->value)) {
                 return $this->value; /*float*/
@@ -56889,16 +56535,12 @@ class ConditionalPredicateTextFieldDefClass {
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      *
-     * @param bool|float|string|null
+     * @param bool|float|string
      * @return bool
      * @throws Exception
      */
-    public static function validateValue(bool|float|string|null $value): bool {
-        if (is_null($value)) {
-            if (!is_null($value)) {
-                throw new Exception("Attribute Error:ConditionalPredicateTextFieldDefClass::value");
-            }
-        } elseif (is_bool($value)) {
+    public static function validateValue(bool|float|string $value): bool {
+        if (is_bool($value)) {
             if (!is_bool($value)) {
                 throw new Exception("Attribute Error:ConditionalPredicateTextFieldDefClass::value");
             }
@@ -56921,9 +56563,9 @@ class ConditionalPredicateTextFieldDefClass {
      * `0` to `1` for opacity).
      *
      * @throws Exception
-     * @return bool|float|string|null
+     * @return bool|float|string
      */
-    public function getValue(): bool|float|string|null {
+    public function getValue(): bool|float|string {
         if (ConditionalPredicateTextFieldDefClass::validateValue($this->value))  {
             return $this->value;
         }
@@ -56934,9 +56576,9 @@ class ConditionalPredicateTextFieldDefClass {
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      *
-     * @return bool|float|string|null
+     * @return bool|float|string
      */
-    public static function sampleValue(): bool|float|string|null {
+    public static function sampleValue(): bool|float|string {
         return true; /*32:value*/
     }
 
@@ -56944,14 +56586,12 @@ class ConditionalPredicateTextFieldDefClass {
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      *
-     * @param stdClass|string|null $value
+     * @param stdClass|string $value
      * @throws Exception
-     * @return Selection|string|null
+     * @return Selection|string
      */
-    public static function fromSelection(stdClass|string|null $value): Selection|string|null {
-        if (is_null($value)) {
-            return $value; /*null*/
-        } elseif (is_object($value)) {
+    public static function fromSelection(stdClass|string $value): Selection|string {
+        if (is_object($value)) {
             return Selection::from($value); /*class*/
         } elseif (is_string($value)) {
             return $value; /*string*/
@@ -56965,13 +56605,11 @@ class ConditionalPredicateTextFieldDefClass {
      * selections](selection.html#compose).
      *
      * @throws Exception
-     * @return stdClass|string|null
+     * @return stdClass|string
      */
-    public function toSelection(): stdClass|string|null {
+    public function toSelection(): stdClass|string {
         if (ConditionalPredicateTextFieldDefClass::validateSelection($this->selection))  {
-            if (is_null($this->selection)) {
-                return $this->selection; /*null*/
-            } elseif ($this->selection instanceof Selection) {
+            if ($this->selection instanceof Selection) {
                 return $this->selection->to(); /*class*/
             } elseif (is_string($this->selection)) {
                 return $this->selection; /*string*/
@@ -56986,16 +56624,12 @@ class ConditionalPredicateTextFieldDefClass {
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      *
-     * @param Selection|string|null
+     * @param Selection|string
      * @return bool
      * @throws Exception
      */
-    public static function validateSelection(Selection|string|null $value): bool {
-        if (is_null($value)) {
-            if (!is_null($value)) {
-                throw new Exception("Attribute Error:ConditionalPredicateTextFieldDefClass::selection");
-            }
-        } elseif ($value instanceof Selection) {
+    public static function validateSelection(Selection|string $value): bool {
+        if ($value instanceof Selection) {
             $value->validate();
         } elseif (is_string($value)) {
             if (!is_string($value)) {
@@ -57012,9 +56646,9 @@ class ConditionalPredicateTextFieldDefClass {
      * selections](selection.html#compose).
      *
      * @throws Exception
-     * @return Selection|string|null
+     * @return Selection|string
      */
-    public function getSelection(): Selection|string|null {
+    public function getSelection(): Selection|string {
         if (ConditionalPredicateTextFieldDefClass::validateSelection($this->selection))  {
             return $this->selection;
         }
@@ -57025,9 +56659,9 @@ class ConditionalPredicateTextFieldDefClass {
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      *
-     * @return Selection|string|null
+     * @return Selection|string
      */
-    public static function sampleSelection(): Selection|string|null {
+    public static function sampleSelection(): Selection|string {
         return Selection::sample(); /*33:selection*/
     }
 
@@ -57512,16 +57146,12 @@ class ConditionalPredicateTextFieldDefClass {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      *
-     * @param ?string $value
+     * @param string $value
      * @throws Exception
-     * @return ?Type
+     * @return Type
      */
-    public static function fromType(?string $value): ?Type {
-        if (!is_null($value)) {
-            return Type::from($value); /*enum*/
-        } else {
-            return  null;
-        }
+    public static function fromType(string $value): Type {
+        return Type::from($value); /*enum*/
     }
 
     /**
@@ -57531,15 +57161,11 @@ class ConditionalPredicateTextFieldDefClass {
      * [geographic projection](projection.html) is applied.
      *
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public function toType(): ?string {
+    public function toType(): string {
         if (ConditionalPredicateTextFieldDefClass::validateType($this->type))  {
-            if (!is_null($this->type)) {
-                return Type::to($this->type); /*enum*/
-            } else {
-                return  null;
-            }
+            return Type::to($this->type); /*enum*/
         }
         throw new Exception('never get to this ConditionalPredicateTextFieldDefClass::type');
     }
@@ -57550,14 +57176,12 @@ class ConditionalPredicateTextFieldDefClass {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      *
-     * @param Type|null
+     * @param Type
      * @return bool
      * @throws Exception
      */
-    public static function validateType(?Type $value): bool {
-        if (!is_null($value)) {
-            Type::to($value);
-        }
+    public static function validateType(Type $value): bool {
+        Type::to($value);
         return true;
     }
 
@@ -57568,9 +57192,9 @@ class ConditionalPredicateTextFieldDefClass {
      * [geographic projection](projection.html) is applied.
      *
      * @throws Exception
-     * @return ?Type
+     * @return Type
      */
-    public function getType(): ?Type {
+    public function getType(): Type {
         if (ConditionalPredicateTextFieldDefClass::validateType($this->type))  {
             return $this->type;
         }
@@ -57583,9 +57207,9 @@ class ConditionalPredicateTextFieldDefClass {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      *
-     * @return ?Type
+     * @return Type
      */
-    public static function sampleType(): ?Type {
+    public static function sampleType(): Type {
         return Type::sample(); /*enum*/
     }
 
@@ -57671,8 +57295,8 @@ class XClass {
     private SortField|SortOrder|null $sort; // json:sort Optional
     private ?StackOffset $stack; // json:stack Optional
     private ?TimeUnit $timeUnit; // json:timeUnit Optional
-    private ?Type $type; // json:type Optional
-    private bool|float|string|null $value; // json:value Optional
+    private Type $type; // json:type Required
+    private bool|float|string $value; // json:value Required
 
     /**
      * @param AggregateOp|null $aggregate
@@ -57683,10 +57307,10 @@ class XClass {
      * @param SortField|SortOrder|null $sort
      * @param StackOffset|null $stack
      * @param TimeUnit|null $timeUnit
-     * @param Type|null $type
-     * @param bool|float|string|null $value
+     * @param Type $type
+     * @param bool|float|string $value
      */
-    public function __construct(?AggregateOp $aggregate, ?Axis $axis, BinParams|bool|null $bin, RepeatRef|string|null $field, ?Scale $scale, SortField|SortOrder|null $sort, ?StackOffset $stack, ?TimeUnit $timeUnit, ?Type $type, bool|float|string|null $value) {
+    public function __construct(?AggregateOp $aggregate, ?Axis $axis, BinParams|bool|null $bin, RepeatRef|string|null $field, ?Scale $scale, SortField|SortOrder|null $sort, ?StackOffset $stack, ?TimeUnit $timeUnit, Type $type, bool|float|string $value) {
         $this->aggregate = $aggregate;
         $this->axis = $axis;
         $this->bin = $bin;
@@ -58551,16 +58175,12 @@ class XClass {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      *
-     * @param ?string $value
+     * @param string $value
      * @throws Exception
-     * @return ?Type
+     * @return Type
      */
-    public static function fromType(?string $value): ?Type {
-        if (!is_null($value)) {
-            return Type::from($value); /*enum*/
-        } else {
-            return  null;
-        }
+    public static function fromType(string $value): Type {
+        return Type::from($value); /*enum*/
     }
 
     /**
@@ -58570,15 +58190,11 @@ class XClass {
      * [geographic projection](projection.html) is applied.
      *
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public function toType(): ?string {
+    public function toType(): string {
         if (XClass::validateType($this->type))  {
-            if (!is_null($this->type)) {
-                return Type::to($this->type); /*enum*/
-            } else {
-                return  null;
-            }
+            return Type::to($this->type); /*enum*/
         }
         throw new Exception('never get to this XClass::type');
     }
@@ -58589,14 +58205,12 @@ class XClass {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      *
-     * @param Type|null
+     * @param Type
      * @return bool
      * @throws Exception
      */
-    public static function validateType(?Type $value): bool {
-        if (!is_null($value)) {
-            Type::to($value);
-        }
+    public static function validateType(Type $value): bool {
+        Type::to($value);
         return true;
     }
 
@@ -58607,9 +58221,9 @@ class XClass {
      * [geographic projection](projection.html) is applied.
      *
      * @throws Exception
-     * @return ?Type
+     * @return Type
      */
-    public function getType(): ?Type {
+    public function getType(): Type {
         if (XClass::validateType($this->type))  {
             return $this->type;
         }
@@ -58622,9 +58236,9 @@ class XClass {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      *
-     * @return ?Type
+     * @return Type
      */
-    public static function sampleType(): ?Type {
+    public static function sampleType(): Type {
         return Type::sample(); /*enum*/
     }
 
@@ -58632,14 +58246,12 @@ class XClass {
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      *
-     * @param bool|float|string|null $value
+     * @param bool|float|string $value
      * @throws Exception
-     * @return bool|float|string|null
+     * @return bool|float|string
      */
-    public static function fromValue(bool|float|string|null $value): bool|float|string|null {
-        if (is_null($value)) {
-            return $value; /*null*/
-        } elseif (is_bool($value)) {
+    public static function fromValue(bool|float|string $value): bool|float|string {
+        if (is_bool($value)) {
             return $value; /*bool*/
         } elseif (is_float($value) || is_int($value)) {
             return $value; /*float*/
@@ -58655,13 +58267,11 @@ class XClass {
      * `0` to `1` for opacity).
      *
      * @throws Exception
-     * @return bool|float|string|null
+     * @return bool|float|string
      */
-    public function toValue(): bool|float|string|null {
+    public function toValue(): bool|float|string {
         if (XClass::validateValue($this->value))  {
-            if (is_null($this->value)) {
-                return $this->value; /*null*/
-            } elseif (is_bool($this->value)) {
+            if (is_bool($this->value)) {
                 return $this->value; /*bool*/
             } elseif (is_float($this->value) || is_int($this->value)) {
                 return $this->value; /*float*/
@@ -58678,16 +58288,12 @@ class XClass {
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      *
-     * @param bool|float|string|null
+     * @param bool|float|string
      * @return bool
      * @throws Exception
      */
-    public static function validateValue(bool|float|string|null $value): bool {
-        if (is_null($value)) {
-            if (!is_null($value)) {
-                throw new Exception("Attribute Error:XClass::value");
-            }
-        } elseif (is_bool($value)) {
+    public static function validateValue(bool|float|string $value): bool {
+        if (is_bool($value)) {
             if (!is_bool($value)) {
                 throw new Exception("Attribute Error:XClass::value");
             }
@@ -58710,9 +58316,9 @@ class XClass {
      * `0` to `1` for opacity).
      *
      * @throws Exception
-     * @return bool|float|string|null
+     * @return bool|float|string
      */
-    public function getValue(): bool|float|string|null {
+    public function getValue(): bool|float|string {
         if (XClass::validateValue($this->value))  {
             return $this->value;
         }
@@ -58723,9 +58329,9 @@ class XClass {
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      *
-     * @return bool|float|string|null
+     * @return bool|float|string
      */
-    public static function sampleValue(): bool|float|string|null {
+    public static function sampleValue(): bool|float|string {
         return true; /*40:value*/
     }
 
@@ -60957,18 +60563,18 @@ class X2Class {
     private BinParams|bool|null $bin; // json:bin Optional
     private RepeatRef|string|null $field; // json:field Optional
     private ?TimeUnit $timeUnit; // json:timeUnit Optional
-    private ?Type $type; // json:type Optional
-    private bool|float|string|null $value; // json:value Optional
+    private Type $type; // json:type Required
+    private bool|float|string $value; // json:value Required
 
     /**
      * @param AggregateOp|null $aggregate
      * @param BinParams|bool|null $bin
      * @param RepeatRef|string|null $field
      * @param TimeUnit|null $timeUnit
-     * @param Type|null $type
-     * @param bool|float|string|null $value
+     * @param Type $type
+     * @param bool|float|string $value
      */
-    public function __construct(?AggregateOp $aggregate, BinParams|bool|null $bin, RepeatRef|string|null $field, ?TimeUnit $timeUnit, ?Type $type, bool|float|string|null $value) {
+    public function __construct(?AggregateOp $aggregate, BinParams|bool|null $bin, RepeatRef|string|null $field, ?TimeUnit $timeUnit, Type $type, bool|float|string $value) {
         $this->aggregate = $aggregate;
         $this->bin = $bin;
         $this->field = $field;
@@ -61386,16 +60992,12 @@ class X2Class {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      *
-     * @param ?string $value
+     * @param string $value
      * @throws Exception
-     * @return ?Type
+     * @return Type
      */
-    public static function fromType(?string $value): ?Type {
-        if (!is_null($value)) {
-            return Type::from($value); /*enum*/
-        } else {
-            return  null;
-        }
+    public static function fromType(string $value): Type {
+        return Type::from($value); /*enum*/
     }
 
     /**
@@ -61405,15 +61007,11 @@ class X2Class {
      * [geographic projection](projection.html) is applied.
      *
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public function toType(): ?string {
+    public function toType(): string {
         if (X2Class::validateType($this->type))  {
-            if (!is_null($this->type)) {
-                return Type::to($this->type); /*enum*/
-            } else {
-                return  null;
-            }
+            return Type::to($this->type); /*enum*/
         }
         throw new Exception('never get to this X2Class::type');
     }
@@ -61424,14 +61022,12 @@ class X2Class {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      *
-     * @param Type|null
+     * @param Type
      * @return bool
      * @throws Exception
      */
-    public static function validateType(?Type $value): bool {
-        if (!is_null($value)) {
-            Type::to($value);
-        }
+    public static function validateType(Type $value): bool {
+        Type::to($value);
         return true;
     }
 
@@ -61442,9 +61038,9 @@ class X2Class {
      * [geographic projection](projection.html) is applied.
      *
      * @throws Exception
-     * @return ?Type
+     * @return Type
      */
-    public function getType(): ?Type {
+    public function getType(): Type {
         if (X2Class::validateType($this->type))  {
             return $this->type;
         }
@@ -61457,9 +61053,9 @@ class X2Class {
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      *
-     * @return ?Type
+     * @return Type
      */
-    public static function sampleType(): ?Type {
+    public static function sampleType(): Type {
         return Type::sample(); /*enum*/
     }
 
@@ -61467,14 +61063,12 @@ class X2Class {
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      *
-     * @param bool|float|string|null $value
+     * @param bool|float|string $value
      * @throws Exception
-     * @return bool|float|string|null
+     * @return bool|float|string
      */
-    public static function fromValue(bool|float|string|null $value): bool|float|string|null {
-        if (is_null($value)) {
-            return $value; /*null*/
-        } elseif (is_bool($value)) {
+    public static function fromValue(bool|float|string $value): bool|float|string {
+        if (is_bool($value)) {
             return $value; /*bool*/
         } elseif (is_float($value) || is_int($value)) {
             return $value; /*float*/
@@ -61490,13 +61084,11 @@ class X2Class {
      * `0` to `1` for opacity).
      *
      * @throws Exception
-     * @return bool|float|string|null
+     * @return bool|float|string
      */
-    public function toValue(): bool|float|string|null {
+    public function toValue(): bool|float|string {
         if (X2Class::validateValue($this->value))  {
-            if (is_null($this->value)) {
-                return $this->value; /*null*/
-            } elseif (is_bool($this->value)) {
+            if (is_bool($this->value)) {
                 return $this->value; /*bool*/
             } elseif (is_float($this->value) || is_int($this->value)) {
                 return $this->value; /*float*/
@@ -61513,16 +61105,12 @@ class X2Class {
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      *
-     * @param bool|float|string|null
+     * @param bool|float|string
      * @return bool
      * @throws Exception
      */
-    public static function validateValue(bool|float|string|null $value): bool {
-        if (is_null($value)) {
-            if (!is_null($value)) {
-                throw new Exception("Attribute Error:X2Class::value");
-            }
-        } elseif (is_bool($value)) {
+    public static function validateValue(bool|float|string $value): bool {
+        if (is_bool($value)) {
             if (!is_bool($value)) {
                 throw new Exception("Attribute Error:X2Class::value");
             }
@@ -61545,9 +61133,9 @@ class X2Class {
      * `0` to `1` for opacity).
      *
      * @throws Exception
-     * @return bool|float|string|null
+     * @return bool|float|string
      */
-    public function getValue(): bool|float|string|null {
+    public function getValue(): bool|float|string {
         if (X2Class::validateValue($this->value))  {
             return $this->value;
         }
@@ -61558,9 +61146,9 @@ class X2Class {
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      *
-     * @return bool|float|string|null
+     * @return bool|float|string
      */
-    public static function sampleValue(): bool|float|string|null {
+    public static function sampleValue(): bool|float|string {
         return true; /*36:value*/
     }
 
@@ -61823,43 +61411,43 @@ class Spec {
     private ?Data $data; // json:data Optional
     private ?string $description; // json:description Optional
     private ?float $height; // json:height Optional
-    private ?array $layer; // json:layer Optional
+    private array $layer; // json:layer Required
     private ?string $name; // json:name Optional
     private ?Resolve $resolve; // json:resolve Optional
     private TitleParams|string|null $title; // json:title Optional
     private ?array $transform; // json:transform Optional
     private ?float $width; // json:width Optional
-    private ?Encoding $encoding; // json:encoding Optional
-    private MarkDef|Mark|null $mark; // json:mark Optional
+    private Encoding $encoding; // json:encoding Required
+    private MarkDef|Mark $mark; // json:mark Required
     private ?Projection $projection; // json:projection Optional
     private ?stdClass $selection; // json:selection Optional
-    private ?FacetMapping $facet; // json:facet Optional
-    private ?Spec $spec; // json:spec Optional
-    private ?Repeat $repeat; // json:repeat Optional
-    private ?array $vconcat; // json:vconcat Optional
-    private ?array $hconcat; // json:hconcat Optional
+    private FacetMapping $facet; // json:facet Required
+    private Spec $spec; // json:spec Required
+    private Repeat $repeat; // json:repeat Required
+    private array $vconcat; // json:vconcat Required
+    private array $hconcat; // json:hconcat Required
 
     /**
      * @param Data|null $data
      * @param string|null $description
      * @param float|null $height
-     * @param array|null $layer
+     * @param array $layer
      * @param string|null $name
      * @param Resolve|null $resolve
      * @param TitleParams|string|null $title
      * @param array|null $transform
      * @param float|null $width
-     * @param Encoding|null $encoding
-     * @param MarkDef|Mark|null $mark
+     * @param Encoding $encoding
+     * @param MarkDef|Mark $mark
      * @param Projection|null $projection
      * @param stdClass|null $selection
-     * @param FacetMapping|null $facet
-     * @param Spec|null $spec
-     * @param Repeat|null $repeat
-     * @param array|null $vconcat
-     * @param array|null $hconcat
+     * @param FacetMapping $facet
+     * @param Spec $spec
+     * @param Repeat $repeat
+     * @param array $vconcat
+     * @param array $hconcat
      */
-    public function __construct(?Data $data, ?string $description, ?float $height, ?array $layer, ?string $name, ?Resolve $resolve, TitleParams|string|null $title, ?array $transform, ?float $width, ?Encoding $encoding, MarkDef|Mark|null $mark, ?Projection $projection, ?stdClass $selection, ?FacetMapping $facet, ?Spec $spec, ?Repeat $repeat, ?array $vconcat, ?array $hconcat) {
+    public function __construct(?Data $data, ?string $description, ?float $height, array $layer, ?string $name, ?Resolve $resolve, TitleParams|string|null $title, ?array $transform, ?float $width, Encoding $encoding, MarkDef|Mark $mark, ?Projection $projection, ?stdClass $selection, FacetMapping $facet, Spec $spec, Repeat $repeat, array $vconcat, array $hconcat) {
         $this->data = $data;
         $this->description = $description;
         $this->height = $height;
@@ -62168,18 +61756,14 @@ class Spec {
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      *
-     * @param ?array $value
+     * @param array $value
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public static function fromLayer(?array $value): ?array {
-        if (!is_null($value)) {
-            return  array_map(function ($value) {
-                return LayerSpec::from($value); /*class*/
-            }, $value);
-        } else {
-            return  null;
-        }
+    public static function fromLayer(array $value): array {
+        return  array_map(function ($value) {
+            return LayerSpec::from($value); /*class*/
+        }, $value);
     }
 
     /**
@@ -62189,17 +61773,13 @@ class Spec {
      * layering facet specifications is not allowed.
      *
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function toLayer(): ?array {
+    public function toLayer(): array {
         if (Spec::validateLayer($this->layer))  {
-            if (!is_null($this->layer)) {
-                return array_map(function ($value) {
-                    return $value->to(); /*class*/
-                }, $this->layer);
-            } else {
-                return  null;
-            }
+            return array_map(function ($value) {
+                return $value->to(); /*class*/
+            }, $this->layer);
         }
         throw new Exception('never get to this Spec::layer');
     }
@@ -62210,19 +61790,17 @@ class Spec {
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      *
-     * @param array|null
+     * @param array
      * @return bool
      * @throws Exception
      */
-    public static function validateLayer(?array $value): bool {
-        if (!is_null($value)) {
-            if (!is_array($value)) {
-                throw new Exception("Attribute Error:Spec::layer");
-            }
-            array_walk($value, function($value_v) {
-                $value_v->validate();
-            });
+    public static function validateLayer(array $value): bool {
+        if (!is_array($value)) {
+            throw new Exception("Attribute Error:Spec::layer");
         }
+        array_walk($value, function($value_v) {
+            $value_v->validate();
+        });
         return true;
     }
 
@@ -62233,9 +61811,9 @@ class Spec {
      * layering facet specifications is not allowed.
      *
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function getLayer(): ?array {
+    public function getLayer(): array {
         if (Spec::validateLayer($this->layer))  {
             return $this->layer;
         }
@@ -62248,9 +61826,9 @@ class Spec {
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      *
-     * @return ?array
+     * @return array
      */
-    public static function sampleLayer(): ?array {
+    public static function sampleLayer(): array {
         return  array(
             LayerSpec::sample() /*34:*/
         ); /* 34:layer*/
@@ -62761,31 +62339,23 @@ class Spec {
     /**
      * A key-value mapping between encoding channels and definition of fields.
      *
-     * @param ?stdClass $value
+     * @param stdClass $value
      * @throws Exception
-     * @return ?Encoding
+     * @return Encoding
      */
-    public static function fromEncoding(?stdClass $value): ?Encoding {
-        if (!is_null($value)) {
-            return Encoding::from($value); /*class*/
-        } else {
-            return  null;
-        }
+    public static function fromEncoding(stdClass $value): Encoding {
+        return Encoding::from($value); /*class*/
     }
 
     /**
      * A key-value mapping between encoding channels and definition of fields.
      *
      * @throws Exception
-     * @return ?stdClass
+     * @return stdClass
      */
-    public function toEncoding(): ?stdClass {
+    public function toEncoding(): stdClass {
         if (Spec::validateEncoding($this->encoding))  {
-            if (!is_null($this->encoding)) {
-                return $this->encoding->to(); /*class*/
-            } else {
-                return  null;
-            }
+            return $this->encoding->to(); /*class*/
         }
         throw new Exception('never get to this Spec::encoding');
     }
@@ -62793,14 +62363,12 @@ class Spec {
     /**
      * A key-value mapping between encoding channels and definition of fields.
      *
-     * @param Encoding|null
+     * @param Encoding
      * @return bool
      * @throws Exception
      */
-    public static function validateEncoding(?Encoding $value): bool {
-        if (!is_null($value)) {
-            $value->validate();
-        }
+    public static function validateEncoding(Encoding $value): bool {
+        $value->validate();
         return true;
     }
 
@@ -62808,9 +62376,9 @@ class Spec {
      * A key-value mapping between encoding channels and definition of fields.
      *
      * @throws Exception
-     * @return ?Encoding
+     * @return Encoding
      */
-    public function getEncoding(): ?Encoding {
+    public function getEncoding(): Encoding {
         if (Spec::validateEncoding($this->encoding))  {
             return $this->encoding;
         }
@@ -62820,9 +62388,9 @@ class Spec {
     /**
      * A key-value mapping between encoding channels and definition of fields.
      *
-     * @return ?Encoding
+     * @return Encoding
      */
-    public static function sampleEncoding(): ?Encoding {
+    public static function sampleEncoding(): Encoding {
         return Encoding::sample(); /*40:encoding*/
     }
 
@@ -62832,14 +62400,12 @@ class Spec {
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      *
-     * @param stdClass|string|null $value
+     * @param stdClass|string $value
      * @throws Exception
-     * @return MarkDef|Mark|null
+     * @return MarkDef|Mark
      */
-    public static function fromMark(stdClass|string|null $value): MarkDef|Mark|null {
-        if (is_null($value)) {
-            return $value; /*null*/
-        } elseif (is_object($value)) {
+    public static function fromMark(stdClass|string $value): MarkDef|Mark {
+        if (is_object($value)) {
             return MarkDef::from($value); /*class*/
         } elseif (is_string($value) && in_array($value, ['area', 'bar', 'line', 'point', 'text', 'tick', 'rect', 'rule', 'circle', 'square', 'geoshape'], true)) {
             return Mark::from($value); /*enum*/
@@ -62855,13 +62421,11 @@ class Spec {
      * object](mark.html#mark-def).
      *
      * @throws Exception
-     * @return stdClass|string|null
+     * @return stdClass|string
      */
-    public function toMark(): stdClass|string|null {
+    public function toMark(): stdClass|string {
         if (Spec::validateMark($this->mark))  {
-            if (is_null($this->mark)) {
-                return $this->mark; /*null*/
-            } elseif ($this->mark instanceof MarkDef) {
+            if ($this->mark instanceof MarkDef) {
                 return $this->mark->to(); /*class*/
             } elseif ($this->mark instanceof Mark) {
                 return Mark::to($this->mark); /*enum*/
@@ -62878,16 +62442,12 @@ class Spec {
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      *
-     * @param MarkDef|Mark|null
+     * @param MarkDef|Mark
      * @return bool
      * @throws Exception
      */
-    public static function validateMark(MarkDef|Mark|null $value): bool {
-        if (is_null($value)) {
-            if (!is_null($value)) {
-                throw new Exception("Attribute Error:Spec::mark");
-            }
-        } elseif ($value instanceof MarkDef) {
+    public static function validateMark(MarkDef|Mark $value): bool {
+        if ($value instanceof MarkDef) {
             $value->validate();
         } elseif ($value instanceof Mark) {
             Mark::to($value);
@@ -62904,9 +62464,9 @@ class Spec {
      * object](mark.html#mark-def).
      *
      * @throws Exception
-     * @return MarkDef|Mark|null
+     * @return MarkDef|Mark
      */
-    public function getMark(): MarkDef|Mark|null {
+    public function getMark(): MarkDef|Mark {
         if (Spec::validateMark($this->mark))  {
             return $this->mark;
         }
@@ -62919,9 +62479,9 @@ class Spec {
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      *
-     * @return MarkDef|Mark|null
+     * @return MarkDef|Mark
      */
-    public static function sampleMark(): MarkDef|Mark|null {
+    public static function sampleMark(): MarkDef|Mark {
         return MarkDef::sample(); /*41:mark*/
     }
 
@@ -63094,16 +62654,12 @@ class Spec {
      * An object that describes mappings between `row` and `column` channels and their field
      * definitions.
      *
-     * @param ?stdClass $value
+     * @param stdClass $value
      * @throws Exception
-     * @return ?FacetMapping
+     * @return FacetMapping
      */
-    public static function fromFacet(?stdClass $value): ?FacetMapping {
-        if (!is_null($value)) {
-            return FacetMapping::from($value); /*class*/
-        } else {
-            return  null;
-        }
+    public static function fromFacet(stdClass $value): FacetMapping {
+        return FacetMapping::from($value); /*class*/
     }
 
     /**
@@ -63111,15 +62667,11 @@ class Spec {
      * definitions.
      *
      * @throws Exception
-     * @return ?stdClass
+     * @return stdClass
      */
-    public function toFacet(): ?stdClass {
+    public function toFacet(): stdClass {
         if (Spec::validateFacet($this->facet))  {
-            if (!is_null($this->facet)) {
-                return $this->facet->to(); /*class*/
-            } else {
-                return  null;
-            }
+            return $this->facet->to(); /*class*/
         }
         throw new Exception('never get to this Spec::facet');
     }
@@ -63128,14 +62680,12 @@ class Spec {
      * An object that describes mappings between `row` and `column` channels and their field
      * definitions.
      *
-     * @param FacetMapping|null
+     * @param FacetMapping
      * @return bool
      * @throws Exception
      */
-    public static function validateFacet(?FacetMapping $value): bool {
-        if (!is_null($value)) {
-            $value->validate();
-        }
+    public static function validateFacet(FacetMapping $value): bool {
+        $value->validate();
         return true;
     }
 
@@ -63144,9 +62694,9 @@ class Spec {
      * definitions.
      *
      * @throws Exception
-     * @return ?FacetMapping
+     * @return FacetMapping
      */
-    public function getFacet(): ?FacetMapping {
+    public function getFacet(): FacetMapping {
         if (Spec::validateFacet($this->facet))  {
             return $this->facet;
         }
@@ -63157,40 +62707,32 @@ class Spec {
      * An object that describes mappings between `row` and `column` channels and their field
      * definitions.
      *
-     * @return ?FacetMapping
+     * @return FacetMapping
      */
-    public static function sampleFacet(): ?FacetMapping {
+    public static function sampleFacet(): FacetMapping {
         return FacetMapping::sample(); /*44:facet*/
     }
 
     /**
      * A specification of the view that gets faceted.
      *
-     * @param ?stdClass $value
+     * @param stdClass $value
      * @throws Exception
-     * @return ?Spec
+     * @return Spec
      */
-    public static function fromSpec(?stdClass $value): ?Spec {
-        if (!is_null($value)) {
-            return Spec::from($value); /*class*/
-        } else {
-            return  null;
-        }
+    public static function fromSpec(stdClass $value): Spec {
+        return Spec::from($value); /*class*/
     }
 
     /**
      * A specification of the view that gets faceted.
      *
      * @throws Exception
-     * @return ?stdClass
+     * @return stdClass
      */
-    public function toSpec(): ?stdClass {
+    public function toSpec(): stdClass {
         if (Spec::validateSpec($this->spec))  {
-            if (!is_null($this->spec)) {
-                return $this->spec->to(); /*class*/
-            } else {
-                return  null;
-            }
+            return $this->spec->to(); /*class*/
         }
         throw new Exception('never get to this Spec::spec');
     }
@@ -63198,14 +62740,12 @@ class Spec {
     /**
      * A specification of the view that gets faceted.
      *
-     * @param Spec|null
+     * @param Spec
      * @return bool
      * @throws Exception
      */
-    public static function validateSpec(?Spec $value): bool {
-        if (!is_null($value)) {
-            $value->validate();
-        }
+    public static function validateSpec(Spec $value): bool {
+        $value->validate();
         return true;
     }
 
@@ -63213,9 +62753,9 @@ class Spec {
      * A specification of the view that gets faceted.
      *
      * @throws Exception
-     * @return ?Spec
+     * @return Spec
      */
-    public function getSpec(): ?Spec {
+    public function getSpec(): Spec {
         if (Spec::validateSpec($this->spec))  {
             return $this->spec;
         }
@@ -63225,9 +62765,9 @@ class Spec {
     /**
      * A specification of the view that gets faceted.
      *
-     * @return ?Spec
+     * @return Spec
      */
-    public static function sampleSpec(): ?Spec {
+    public static function sampleSpec(): Spec {
         return Spec::sample(); /*45:spec*/
     }
 
@@ -63235,16 +62775,12 @@ class Spec {
      * An object that describes what fields should be repeated into views that are laid out as a
      * `row` or `column`.
      *
-     * @param ?stdClass $value
+     * @param stdClass $value
      * @throws Exception
-     * @return ?Repeat
+     * @return Repeat
      */
-    public static function fromRepeat(?stdClass $value): ?Repeat {
-        if (!is_null($value)) {
-            return Repeat::from($value); /*class*/
-        } else {
-            return  null;
-        }
+    public static function fromRepeat(stdClass $value): Repeat {
+        return Repeat::from($value); /*class*/
     }
 
     /**
@@ -63252,15 +62788,11 @@ class Spec {
      * `row` or `column`.
      *
      * @throws Exception
-     * @return ?stdClass
+     * @return stdClass
      */
-    public function toRepeat(): ?stdClass {
+    public function toRepeat(): stdClass {
         if (Spec::validateRepeat($this->repeat))  {
-            if (!is_null($this->repeat)) {
-                return $this->repeat->to(); /*class*/
-            } else {
-                return  null;
-            }
+            return $this->repeat->to(); /*class*/
         }
         throw new Exception('never get to this Spec::repeat');
     }
@@ -63269,14 +62801,12 @@ class Spec {
      * An object that describes what fields should be repeated into views that are laid out as a
      * `row` or `column`.
      *
-     * @param Repeat|null
+     * @param Repeat
      * @return bool
      * @throws Exception
      */
-    public static function validateRepeat(?Repeat $value): bool {
-        if (!is_null($value)) {
-            $value->validate();
-        }
+    public static function validateRepeat(Repeat $value): bool {
+        $value->validate();
         return true;
     }
 
@@ -63285,9 +62815,9 @@ class Spec {
      * `row` or `column`.
      *
      * @throws Exception
-     * @return ?Repeat
+     * @return Repeat
      */
-    public function getRepeat(): ?Repeat {
+    public function getRepeat(): Repeat {
         if (Spec::validateRepeat($this->repeat))  {
             return $this->repeat;
         }
@@ -63298,44 +62828,36 @@ class Spec {
      * An object that describes what fields should be repeated into views that are laid out as a
      * `row` or `column`.
      *
-     * @return ?Repeat
+     * @return Repeat
      */
-    public static function sampleRepeat(): ?Repeat {
+    public static function sampleRepeat(): Repeat {
         return Repeat::sample(); /*46:repeat*/
     }
 
     /**
      * A list of views that should be concatenated and put into a column.
      *
-     * @param ?array $value
+     * @param array $value
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public static function fromVconcat(?array $value): ?array {
-        if (!is_null($value)) {
-            return  array_map(function ($value) {
-                return Spec::from($value); /*class*/
-            }, $value);
-        } else {
-            return  null;
-        }
+    public static function fromVconcat(array $value): array {
+        return  array_map(function ($value) {
+            return Spec::from($value); /*class*/
+        }, $value);
     }
 
     /**
      * A list of views that should be concatenated and put into a column.
      *
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function toVconcat(): ?array {
+    public function toVconcat(): array {
         if (Spec::validateVconcat($this->vconcat))  {
-            if (!is_null($this->vconcat)) {
-                return array_map(function ($value) {
-                    return $value->to(); /*class*/
-                }, $this->vconcat);
-            } else {
-                return  null;
-            }
+            return array_map(function ($value) {
+                return $value->to(); /*class*/
+            }, $this->vconcat);
         }
         throw new Exception('never get to this Spec::vconcat');
     }
@@ -63343,19 +62865,17 @@ class Spec {
     /**
      * A list of views that should be concatenated and put into a column.
      *
-     * @param array|null
+     * @param array
      * @return bool
      * @throws Exception
      */
-    public static function validateVconcat(?array $value): bool {
-        if (!is_null($value)) {
-            if (!is_array($value)) {
-                throw new Exception("Attribute Error:Spec::vconcat");
-            }
-            array_walk($value, function($value_v) {
-                $value_v->validate();
-            });
+    public static function validateVconcat(array $value): bool {
+        if (!is_array($value)) {
+            throw new Exception("Attribute Error:Spec::vconcat");
         }
+        array_walk($value, function($value_v) {
+            $value_v->validate();
+        });
         return true;
     }
 
@@ -63363,9 +62883,9 @@ class Spec {
      * A list of views that should be concatenated and put into a column.
      *
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function getVconcat(): ?array {
+    public function getVconcat(): array {
         if (Spec::validateVconcat($this->vconcat))  {
             return $this->vconcat;
         }
@@ -63375,9 +62895,9 @@ class Spec {
     /**
      * A list of views that should be concatenated and put into a column.
      *
-     * @return ?array
+     * @return array
      */
-    public static function sampleVconcat(): ?array {
+    public static function sampleVconcat(): array {
         return  array(
             Spec::sample() /*47:*/
         ); /* 47:vconcat*/
@@ -63386,35 +62906,27 @@ class Spec {
     /**
      * A list of views that should be concatenated and put into a row.
      *
-     * @param ?array $value
+     * @param array $value
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public static function fromHconcat(?array $value): ?array {
-        if (!is_null($value)) {
-            return  array_map(function ($value) {
-                return Spec::from($value); /*class*/
-            }, $value);
-        } else {
-            return  null;
-        }
+    public static function fromHconcat(array $value): array {
+        return  array_map(function ($value) {
+            return Spec::from($value); /*class*/
+        }, $value);
     }
 
     /**
      * A list of views that should be concatenated and put into a row.
      *
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function toHconcat(): ?array {
+    public function toHconcat(): array {
         if (Spec::validateHconcat($this->hconcat))  {
-            if (!is_null($this->hconcat)) {
-                return array_map(function ($value) {
-                    return $value->to(); /*class*/
-                }, $this->hconcat);
-            } else {
-                return  null;
-            }
+            return array_map(function ($value) {
+                return $value->to(); /*class*/
+            }, $this->hconcat);
         }
         throw new Exception('never get to this Spec::hconcat');
     }
@@ -63422,19 +62934,17 @@ class Spec {
     /**
      * A list of views that should be concatenated and put into a row.
      *
-     * @param array|null
+     * @param array
      * @return bool
      * @throws Exception
      */
-    public static function validateHconcat(?array $value): bool {
-        if (!is_null($value)) {
-            if (!is_array($value)) {
-                throw new Exception("Attribute Error:Spec::hconcat");
-            }
-            array_walk($value, function($value_v) {
-                $value_v->validate();
-            });
+    public static function validateHconcat(array $value): bool {
+        if (!is_array($value)) {
+            throw new Exception("Attribute Error:Spec::hconcat");
         }
+        array_walk($value, function($value_v) {
+            $value_v->validate();
+        });
         return true;
     }
 
@@ -63442,9 +62952,9 @@ class Spec {
      * A list of views that should be concatenated and put into a row.
      *
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function getHconcat(): ?array {
+    public function getHconcat(): array {
         if (Spec::validateHconcat($this->hconcat))  {
             return $this->hconcat;
         }
@@ -63454,9 +62964,9 @@ class Spec {
     /**
      * A list of views that should be concatenated and put into a row.
      *
-     * @return ?array
+     * @return array
      */
-    public static function sampleHconcat(): ?array {
+    public static function sampleHconcat(): array {
         return  array(
             Spec::sample() /*48:*/
         ); /* 48:hconcat*/
@@ -64774,14 +64284,14 @@ class LayerSpec {
     private ?Data $data; // json:data Optional
     private ?string $description; // json:description Optional
     private ?float $height; // json:height Optional
-    private ?array $layer; // json:layer Optional
+    private array $layer; // json:layer Required
     private ?string $name; // json:name Optional
     private ?Resolve $resolve; // json:resolve Optional
     private TitleParams|string|null $title; // json:title Optional
     private ?array $transform; // json:transform Optional
     private ?float $width; // json:width Optional
-    private ?Encoding $encoding; // json:encoding Optional
-    private MarkDef|Mark|null $mark; // json:mark Optional
+    private Encoding $encoding; // json:encoding Required
+    private MarkDef|Mark $mark; // json:mark Required
     private ?Projection $projection; // json:projection Optional
     private ?stdClass $selection; // json:selection Optional
 
@@ -64789,18 +64299,18 @@ class LayerSpec {
      * @param Data|null $data
      * @param string|null $description
      * @param float|null $height
-     * @param array|null $layer
+     * @param array $layer
      * @param string|null $name
      * @param Resolve|null $resolve
      * @param TitleParams|string|null $title
      * @param array|null $transform
      * @param float|null $width
-     * @param Encoding|null $encoding
-     * @param MarkDef|Mark|null $mark
+     * @param Encoding $encoding
+     * @param MarkDef|Mark $mark
      * @param Projection|null $projection
      * @param stdClass|null $selection
      */
-    public function __construct(?Data $data, ?string $description, ?float $height, ?array $layer, ?string $name, ?Resolve $resolve, TitleParams|string|null $title, ?array $transform, ?float $width, ?Encoding $encoding, MarkDef|Mark|null $mark, ?Projection $projection, ?stdClass $selection) {
+    public function __construct(?Data $data, ?string $description, ?float $height, array $layer, ?string $name, ?Resolve $resolve, TitleParams|string|null $title, ?array $transform, ?float $width, Encoding $encoding, MarkDef|Mark $mark, ?Projection $projection, ?stdClass $selection) {
         $this->data = $data;
         $this->description = $description;
         $this->height = $height;
@@ -65104,18 +64614,14 @@ class LayerSpec {
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      *
-     * @param ?array $value
+     * @param array $value
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public static function fromLayer(?array $value): ?array {
-        if (!is_null($value)) {
-            return  array_map(function ($value) {
-                return LayerSpec::from($value); /*class*/
-            }, $value);
-        } else {
-            return  null;
-        }
+    public static function fromLayer(array $value): array {
+        return  array_map(function ($value) {
+            return LayerSpec::from($value); /*class*/
+        }, $value);
     }
 
     /**
@@ -65125,17 +64631,13 @@ class LayerSpec {
      * layering facet specifications is not allowed.
      *
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function toLayer(): ?array {
+    public function toLayer(): array {
         if (LayerSpec::validateLayer($this->layer))  {
-            if (!is_null($this->layer)) {
-                return array_map(function ($value) {
-                    return $value->to(); /*class*/
-                }, $this->layer);
-            } else {
-                return  null;
-            }
+            return array_map(function ($value) {
+                return $value->to(); /*class*/
+            }, $this->layer);
         }
         throw new Exception('never get to this LayerSpec::layer');
     }
@@ -65146,19 +64648,17 @@ class LayerSpec {
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      *
-     * @param array|null
+     * @param array
      * @return bool
      * @throws Exception
      */
-    public static function validateLayer(?array $value): bool {
-        if (!is_null($value)) {
-            if (!is_array($value)) {
-                throw new Exception("Attribute Error:LayerSpec::layer");
-            }
-            array_walk($value, function($value_v) {
-                $value_v->validate();
-            });
+    public static function validateLayer(array $value): bool {
+        if (!is_array($value)) {
+            throw new Exception("Attribute Error:LayerSpec::layer");
         }
+        array_walk($value, function($value_v) {
+            $value_v->validate();
+        });
         return true;
     }
 
@@ -65169,9 +64669,9 @@ class LayerSpec {
      * layering facet specifications is not allowed.
      *
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function getLayer(): ?array {
+    public function getLayer(): array {
         if (LayerSpec::validateLayer($this->layer))  {
             return $this->layer;
         }
@@ -65184,9 +64684,9 @@ class LayerSpec {
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      *
-     * @return ?array
+     * @return array
      */
-    public static function sampleLayer(): ?array {
+    public static function sampleLayer(): array {
         return  array(
             LayerSpec::sample() /*34:*/
         ); /* 34:layer*/
@@ -65657,31 +65157,23 @@ class LayerSpec {
     /**
      * A key-value mapping between encoding channels and definition of fields.
      *
-     * @param ?stdClass $value
+     * @param stdClass $value
      * @throws Exception
-     * @return ?Encoding
+     * @return Encoding
      */
-    public static function fromEncoding(?stdClass $value): ?Encoding {
-        if (!is_null($value)) {
-            return Encoding::from($value); /*class*/
-        } else {
-            return  null;
-        }
+    public static function fromEncoding(stdClass $value): Encoding {
+        return Encoding::from($value); /*class*/
     }
 
     /**
      * A key-value mapping between encoding channels and definition of fields.
      *
      * @throws Exception
-     * @return ?stdClass
+     * @return stdClass
      */
-    public function toEncoding(): ?stdClass {
+    public function toEncoding(): stdClass {
         if (LayerSpec::validateEncoding($this->encoding))  {
-            if (!is_null($this->encoding)) {
-                return $this->encoding->to(); /*class*/
-            } else {
-                return  null;
-            }
+            return $this->encoding->to(); /*class*/
         }
         throw new Exception('never get to this LayerSpec::encoding');
     }
@@ -65689,14 +65181,12 @@ class LayerSpec {
     /**
      * A key-value mapping between encoding channels and definition of fields.
      *
-     * @param Encoding|null
+     * @param Encoding
      * @return bool
      * @throws Exception
      */
-    public static function validateEncoding(?Encoding $value): bool {
-        if (!is_null($value)) {
-            $value->validate();
-        }
+    public static function validateEncoding(Encoding $value): bool {
+        $value->validate();
         return true;
     }
 
@@ -65704,9 +65194,9 @@ class LayerSpec {
      * A key-value mapping between encoding channels and definition of fields.
      *
      * @throws Exception
-     * @return ?Encoding
+     * @return Encoding
      */
-    public function getEncoding(): ?Encoding {
+    public function getEncoding(): Encoding {
         if (LayerSpec::validateEncoding($this->encoding))  {
             return $this->encoding;
         }
@@ -65716,9 +65206,9 @@ class LayerSpec {
     /**
      * A key-value mapping between encoding channels and definition of fields.
      *
-     * @return ?Encoding
+     * @return Encoding
      */
-    public static function sampleEncoding(): ?Encoding {
+    public static function sampleEncoding(): Encoding {
         return Encoding::sample(); /*40:encoding*/
     }
 
@@ -65728,14 +65218,12 @@ class LayerSpec {
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      *
-     * @param stdClass|string|null $value
+     * @param stdClass|string $value
      * @throws Exception
-     * @return MarkDef|Mark|null
+     * @return MarkDef|Mark
      */
-    public static function fromMark(stdClass|string|null $value): MarkDef|Mark|null {
-        if (is_null($value)) {
-            return $value; /*null*/
-        } elseif (is_object($value)) {
+    public static function fromMark(stdClass|string $value): MarkDef|Mark {
+        if (is_object($value)) {
             return MarkDef::from($value); /*class*/
         } elseif (is_string($value) && in_array($value, ['area', 'bar', 'line', 'point', 'text', 'tick', 'rect', 'rule', 'circle', 'square', 'geoshape'], true)) {
             return Mark::from($value); /*enum*/
@@ -65751,13 +65239,11 @@ class LayerSpec {
      * object](mark.html#mark-def).
      *
      * @throws Exception
-     * @return stdClass|string|null
+     * @return stdClass|string
      */
-    public function toMark(): stdClass|string|null {
+    public function toMark(): stdClass|string {
         if (LayerSpec::validateMark($this->mark))  {
-            if (is_null($this->mark)) {
-                return $this->mark; /*null*/
-            } elseif ($this->mark instanceof MarkDef) {
+            if ($this->mark instanceof MarkDef) {
                 return $this->mark->to(); /*class*/
             } elseif ($this->mark instanceof Mark) {
                 return Mark::to($this->mark); /*enum*/
@@ -65774,16 +65260,12 @@ class LayerSpec {
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      *
-     * @param MarkDef|Mark|null
+     * @param MarkDef|Mark
      * @return bool
      * @throws Exception
      */
-    public static function validateMark(MarkDef|Mark|null $value): bool {
-        if (is_null($value)) {
-            if (!is_null($value)) {
-                throw new Exception("Attribute Error:LayerSpec::mark");
-            }
-        } elseif ($value instanceof MarkDef) {
+    public static function validateMark(MarkDef|Mark $value): bool {
+        if ($value instanceof MarkDef) {
             $value->validate();
         } elseif ($value instanceof Mark) {
             Mark::to($value);
@@ -65800,9 +65282,9 @@ class LayerSpec {
      * object](mark.html#mark-def).
      *
      * @throws Exception
-     * @return MarkDef|Mark|null
+     * @return MarkDef|Mark
      */
-    public function getMark(): MarkDef|Mark|null {
+    public function getMark(): MarkDef|Mark {
         if (LayerSpec::validateMark($this->mark))  {
             return $this->mark;
         }
@@ -65815,9 +65297,9 @@ class LayerSpec {
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      *
-     * @return MarkDef|Mark|null
+     * @return MarkDef|Mark
      */
-    public static function sampleMark(): MarkDef|Mark|null {
+    public static function sampleMark(): MarkDef|Mark {
         return MarkDef::sample(); /*41:mark*/
     }
 
@@ -73349,32 +72831,32 @@ class TitleParams {
 // This is an autogenerated file:Transform
 
 class Transform {
-    private Predicate|string|null $filter; // json:filter Optional
+    private Predicate|string $filter; // json:filter Required
     private array|string|null $as; // json:as Optional
-    private ?string $calculate; // json:calculate Optional
+    private string $calculate; // json:calculate Required
     private ?string $default; // json:default Optional
-    private ?LookupData $from; // json:from Optional
-    private ?string $lookup; // json:lookup Optional
-    private BinParams|bool|null $bin; // json:bin Optional
-    private ?string $field; // json:field Optional
-    private ?TimeUnit $timeUnit; // json:timeUnit Optional
-    private ?array $aggregate; // json:aggregate Optional
+    private LookupData $from; // json:from Required
+    private string $lookup; // json:lookup Required
+    private BinParams|bool $bin; // json:bin Required
+    private string $field; // json:field Required
+    private TimeUnit $timeUnit; // json:timeUnit Required
+    private array $aggregate; // json:aggregate Required
     private ?array $groupby; // json:groupby Optional
 
     /**
-     * @param Predicate|string|null $filter
+     * @param Predicate|string $filter
      * @param array|string|null $as
-     * @param string|null $calculate
+     * @param string $calculate
      * @param string|null $default
-     * @param LookupData|null $from
-     * @param string|null $lookup
-     * @param BinParams|bool|null $bin
-     * @param string|null $field
-     * @param TimeUnit|null $timeUnit
-     * @param array|null $aggregate
+     * @param LookupData $from
+     * @param string $lookup
+     * @param BinParams|bool $bin
+     * @param string $field
+     * @param TimeUnit $timeUnit
+     * @param array $aggregate
      * @param array|null $groupby
      */
-    public function __construct(Predicate|string|null $filter, array|string|null $as, ?string $calculate, ?string $default, ?LookupData $from, ?string $lookup, BinParams|bool|null $bin, ?string $field, ?TimeUnit $timeUnit, ?array $aggregate, ?array $groupby) {
+    public function __construct(Predicate|string $filter, array|string|null $as, string $calculate, ?string $default, LookupData $from, string $lookup, BinParams|bool $bin, string $field, TimeUnit $timeUnit, array $aggregate, ?array $groupby) {
         $this->filter = $filter;
         $this->as = $as;
         $this->calculate = $calculate;
@@ -73398,14 +72880,12 @@ class Transform {
      * (3) a [selection predicate](filter.html#selection-predicate);
      * or (4) a logical operand that combines (1), (2), or (3).
      *
-     * @param stdClass|string|null $value
+     * @param stdClass|string $value
      * @throws Exception
-     * @return Predicate|string|null
+     * @return Predicate|string
      */
-    public static function fromFilter(stdClass|string|null $value): Predicate|string|null {
-        if (is_null($value)) {
-            return $value; /*null*/
-        } elseif (is_object($value)) {
+    public static function fromFilter(stdClass|string $value): Predicate|string {
+        if (is_object($value)) {
             return Predicate::from($value); /*class*/
         } elseif (is_string($value)) {
             return $value; /*string*/
@@ -73425,13 +72905,11 @@ class Transform {
      * or (4) a logical operand that combines (1), (2), or (3).
      *
      * @throws Exception
-     * @return stdClass|string|null
+     * @return stdClass|string
      */
-    public function toFilter(): stdClass|string|null {
+    public function toFilter(): stdClass|string {
         if (Transform::validateFilter($this->filter))  {
-            if (is_null($this->filter)) {
-                return $this->filter; /*null*/
-            } elseif ($this->filter instanceof Predicate) {
+            if ($this->filter instanceof Predicate) {
                 return $this->filter->to(); /*class*/
             } elseif (is_string($this->filter)) {
                 return $this->filter; /*string*/
@@ -73452,16 +72930,12 @@ class Transform {
      * (3) a [selection predicate](filter.html#selection-predicate);
      * or (4) a logical operand that combines (1), (2), or (3).
      *
-     * @param Predicate|string|null
+     * @param Predicate|string
      * @return bool
      * @throws Exception
      */
-    public static function validateFilter(Predicate|string|null $value): bool {
-        if (is_null($value)) {
-            if (!is_null($value)) {
-                throw new Exception("Attribute Error:Transform::filter");
-            }
-        } elseif ($value instanceof Predicate) {
+    public static function validateFilter(Predicate|string $value): bool {
+        if ($value instanceof Predicate) {
             $value->validate();
         } elseif (is_string($value)) {
             if (!is_string($value)) {
@@ -73484,9 +72958,9 @@ class Transform {
      * or (4) a logical operand that combines (1), (2), or (3).
      *
      * @throws Exception
-     * @return Predicate|string|null
+     * @return Predicate|string
      */
-    public function getFilter(): Predicate|string|null {
+    public function getFilter(): Predicate|string {
         if (Transform::validateFilter($this->filter))  {
             return $this->filter;
         }
@@ -73503,9 +72977,9 @@ class Transform {
      * (3) a [selection predicate](filter.html#selection-predicate);
      * or (4) a logical operand that combines (1), (2), or (3).
      *
-     * @return Predicate|string|null
+     * @return Predicate|string
      */
-    public static function sampleFilter(): Predicate|string|null {
+    public static function sampleFilter(): Predicate|string {
         return Predicate::sample(); /*31:filter*/
     }
 
@@ -73657,16 +73131,12 @@ class Transform {
      * A [expression](types.html#expression) string. Use the variable `datum` to refer to the
      * current data object.
      *
-     * @param ?string $value
+     * @param string $value
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public static function fromCalculate(?string $value): ?string {
-        if (!is_null($value)) {
-            return $value; /*string*/
-        } else {
-            return  null;
-        }
+    public static function fromCalculate(string $value): string {
+        return $value; /*string*/
     }
 
     /**
@@ -73674,15 +73144,11 @@ class Transform {
      * current data object.
      *
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public function toCalculate(): ?string {
+    public function toCalculate(): string {
         if (Transform::validateCalculate($this->calculate))  {
-            if (!is_null($this->calculate)) {
-                return $this->calculate; /*string*/
-            } else {
-                return  null;
-            }
+            return $this->calculate; /*string*/
         }
         throw new Exception('never get to this Transform::calculate');
     }
@@ -73691,13 +73157,11 @@ class Transform {
      * A [expression](types.html#expression) string. Use the variable `datum` to refer to the
      * current data object.
      *
-     * @param string|null
+     * @param string
      * @return bool
      * @throws Exception
      */
-    public static function validateCalculate(?string $value): bool {
-        if (!is_null($value)) {
-        }
+    public static function validateCalculate(string $value): bool {
         return true;
     }
 
@@ -73706,9 +73170,9 @@ class Transform {
      * current data object.
      *
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public function getCalculate(): ?string {
+    public function getCalculate(): string {
         if (Transform::validateCalculate($this->calculate))  {
             return $this->calculate;
         }
@@ -73719,9 +73183,9 @@ class Transform {
      * A [expression](types.html#expression) string. Use the variable `datum` to refer to the
      * current data object.
      *
-     * @return ?string
+     * @return string
      */
-    public static function sampleCalculate(): ?string {
+    public static function sampleCalculate(): string {
         return 'Transform::calculate::33'; /*33:calculate*/
     }
 
@@ -73805,31 +73269,23 @@ class Transform {
     /**
      * Secondary data reference.
      *
-     * @param ?stdClass $value
+     * @param stdClass $value
      * @throws Exception
-     * @return ?LookupData
+     * @return LookupData
      */
-    public static function fromFrom(?stdClass $value): ?LookupData {
-        if (!is_null($value)) {
-            return LookupData::from($value); /*class*/
-        } else {
-            return  null;
-        }
+    public static function fromFrom(stdClass $value): LookupData {
+        return LookupData::from($value); /*class*/
     }
 
     /**
      * Secondary data reference.
      *
      * @throws Exception
-     * @return ?stdClass
+     * @return stdClass
      */
-    public function toFrom(): ?stdClass {
+    public function toFrom(): stdClass {
         if (Transform::validateFrom($this->from))  {
-            if (!is_null($this->from)) {
-                return $this->from->to(); /*class*/
-            } else {
-                return  null;
-            }
+            return $this->from->to(); /*class*/
         }
         throw new Exception('never get to this Transform::from');
     }
@@ -73837,14 +73293,12 @@ class Transform {
     /**
      * Secondary data reference.
      *
-     * @param LookupData|null
+     * @param LookupData
      * @return bool
      * @throws Exception
      */
-    public static function validateFrom(?LookupData $value): bool {
-        if (!is_null($value)) {
-            $value->validate();
-        }
+    public static function validateFrom(LookupData $value): bool {
+        $value->validate();
         return true;
     }
 
@@ -73852,9 +73306,9 @@ class Transform {
      * Secondary data reference.
      *
      * @throws Exception
-     * @return ?LookupData
+     * @return LookupData
      */
-    public function getFrom(): ?LookupData {
+    public function getFrom(): LookupData {
         if (Transform::validateFrom($this->from))  {
             return $this->from;
         }
@@ -73864,40 +73318,32 @@ class Transform {
     /**
      * Secondary data reference.
      *
-     * @return ?LookupData
+     * @return LookupData
      */
-    public static function sampleFrom(): ?LookupData {
+    public static function sampleFrom(): LookupData {
         return LookupData::sample(); /*35:from*/
     }
 
     /**
      * Key in primary data source.
      *
-     * @param ?string $value
+     * @param string $value
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public static function fromLookup(?string $value): ?string {
-        if (!is_null($value)) {
-            return $value; /*string*/
-        } else {
-            return  null;
-        }
+    public static function fromLookup(string $value): string {
+        return $value; /*string*/
     }
 
     /**
      * Key in primary data source.
      *
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public function toLookup(): ?string {
+    public function toLookup(): string {
         if (Transform::validateLookup($this->lookup))  {
-            if (!is_null($this->lookup)) {
-                return $this->lookup; /*string*/
-            } else {
-                return  null;
-            }
+            return $this->lookup; /*string*/
         }
         throw new Exception('never get to this Transform::lookup');
     }
@@ -73905,13 +73351,11 @@ class Transform {
     /**
      * Key in primary data source.
      *
-     * @param string|null
+     * @param string
      * @return bool
      * @throws Exception
      */
-    public static function validateLookup(?string $value): bool {
-        if (!is_null($value)) {
-        }
+    public static function validateLookup(string $value): bool {
         return true;
     }
 
@@ -73919,9 +73363,9 @@ class Transform {
      * Key in primary data source.
      *
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public function getLookup(): ?string {
+    public function getLookup(): string {
         if (Transform::validateLookup($this->lookup))  {
             return $this->lookup;
         }
@@ -73931,23 +73375,21 @@ class Transform {
     /**
      * Key in primary data source.
      *
-     * @return ?string
+     * @return string
      */
-    public static function sampleLookup(): ?string {
+    public static function sampleLookup(): string {
         return 'Transform::lookup::36'; /*36:lookup*/
     }
 
     /**
      * An object indicating bin properties, or simply `true` for using default bin parameters.
      *
-     * @param stdClass|bool|null $value
+     * @param stdClass|bool $value
      * @throws Exception
-     * @return BinParams|bool|null
+     * @return BinParams|bool
      */
-    public static function fromBin(stdClass|bool|null $value): BinParams|bool|null {
-        if (is_null($value)) {
-            return $value; /*null*/
-        } elseif (is_object($value)) {
+    public static function fromBin(stdClass|bool $value): BinParams|bool {
+        if (is_object($value)) {
             return BinParams::from($value); /*class*/
         } elseif (is_bool($value)) {
             return $value; /*bool*/
@@ -73960,13 +73402,11 @@ class Transform {
      * An object indicating bin properties, or simply `true` for using default bin parameters.
      *
      * @throws Exception
-     * @return stdClass|bool|null
+     * @return stdClass|bool
      */
-    public function toBin(): stdClass|bool|null {
+    public function toBin(): stdClass|bool {
         if (Transform::validateBin($this->bin))  {
-            if (is_null($this->bin)) {
-                return $this->bin; /*null*/
-            } elseif ($this->bin instanceof BinParams) {
+            if ($this->bin instanceof BinParams) {
                 return $this->bin->to(); /*class*/
             } elseif (is_bool($this->bin)) {
                 return $this->bin; /*bool*/
@@ -73980,16 +73420,12 @@ class Transform {
     /**
      * An object indicating bin properties, or simply `true` for using default bin parameters.
      *
-     * @param BinParams|bool|null
+     * @param BinParams|bool
      * @return bool
      * @throws Exception
      */
-    public static function validateBin(BinParams|bool|null $value): bool {
-        if (is_null($value)) {
-            if (!is_null($value)) {
-                throw new Exception("Attribute Error:Transform::bin");
-            }
-        } elseif ($value instanceof BinParams) {
+    public static function validateBin(BinParams|bool $value): bool {
+        if ($value instanceof BinParams) {
             $value->validate();
         } elseif (is_bool($value)) {
             if (!is_bool($value)) {
@@ -74005,9 +73441,9 @@ class Transform {
      * An object indicating bin properties, or simply `true` for using default bin parameters.
      *
      * @throws Exception
-     * @return BinParams|bool|null
+     * @return BinParams|bool
      */
-    public function getBin(): BinParams|bool|null {
+    public function getBin(): BinParams|bool {
         if (Transform::validateBin($this->bin))  {
             return $this->bin;
         }
@@ -74017,9 +73453,9 @@ class Transform {
     /**
      * An object indicating bin properties, or simply `true` for using default bin parameters.
      *
-     * @return BinParams|bool|null
+     * @return BinParams|bool
      */
-    public static function sampleBin(): BinParams|bool|null {
+    public static function sampleBin(): BinParams|bool {
         return BinParams::sample(); /*37:bin*/
     }
 
@@ -74028,16 +73464,12 @@ class Transform {
      *
      * The data field to apply time unit.
      *
-     * @param ?string $value
+     * @param string $value
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public static function fromField(?string $value): ?string {
-        if (!is_null($value)) {
-            return $value; /*string*/
-        } else {
-            return  null;
-        }
+    public static function fromField(string $value): string {
+        return $value; /*string*/
     }
 
     /**
@@ -74046,15 +73478,11 @@ class Transform {
      * The data field to apply time unit.
      *
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public function toField(): ?string {
+    public function toField(): string {
         if (Transform::validateField($this->field))  {
-            if (!is_null($this->field)) {
-                return $this->field; /*string*/
-            } else {
-                return  null;
-            }
+            return $this->field; /*string*/
         }
         throw new Exception('never get to this Transform::field');
     }
@@ -74064,13 +73492,11 @@ class Transform {
      *
      * The data field to apply time unit.
      *
-     * @param string|null
+     * @param string
      * @return bool
      * @throws Exception
      */
-    public static function validateField(?string $value): bool {
-        if (!is_null($value)) {
-        }
+    public static function validateField(string $value): bool {
         return true;
     }
 
@@ -74080,9 +73506,9 @@ class Transform {
      * The data field to apply time unit.
      *
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public function getField(): ?string {
+    public function getField(): string {
         if (Transform::validateField($this->field))  {
             return $this->field;
         }
@@ -74094,40 +73520,32 @@ class Transform {
      *
      * The data field to apply time unit.
      *
-     * @return ?string
+     * @return string
      */
-    public static function sampleField(): ?string {
+    public static function sampleField(): string {
         return 'Transform::field::38'; /*38:field*/
     }
 
     /**
      * The timeUnit.
      *
-     * @param ?string $value
+     * @param string $value
      * @throws Exception
-     * @return ?TimeUnit
+     * @return TimeUnit
      */
-    public static function fromTimeUnit(?string $value): ?TimeUnit {
-        if (!is_null($value)) {
-            return TimeUnit::from($value); /*enum*/
-        } else {
-            return  null;
-        }
+    public static function fromTimeUnit(string $value): TimeUnit {
+        return TimeUnit::from($value); /*enum*/
     }
 
     /**
      * The timeUnit.
      *
      * @throws Exception
-     * @return ?string
+     * @return string
      */
-    public function toTimeUnit(): ?string {
+    public function toTimeUnit(): string {
         if (Transform::validateTimeUnit($this->timeUnit))  {
-            if (!is_null($this->timeUnit)) {
-                return TimeUnit::to($this->timeUnit); /*enum*/
-            } else {
-                return  null;
-            }
+            return TimeUnit::to($this->timeUnit); /*enum*/
         }
         throw new Exception('never get to this Transform::timeUnit');
     }
@@ -74135,14 +73553,12 @@ class Transform {
     /**
      * The timeUnit.
      *
-     * @param TimeUnit|null
+     * @param TimeUnit
      * @return bool
      * @throws Exception
      */
-    public static function validateTimeUnit(?TimeUnit $value): bool {
-        if (!is_null($value)) {
-            TimeUnit::to($value);
-        }
+    public static function validateTimeUnit(TimeUnit $value): bool {
+        TimeUnit::to($value);
         return true;
     }
 
@@ -74150,9 +73566,9 @@ class Transform {
      * The timeUnit.
      *
      * @throws Exception
-     * @return ?TimeUnit
+     * @return TimeUnit
      */
-    public function getTimeUnit(): ?TimeUnit {
+    public function getTimeUnit(): TimeUnit {
         if (Transform::validateTimeUnit($this->timeUnit))  {
             return $this->timeUnit;
         }
@@ -74162,44 +73578,36 @@ class Transform {
     /**
      * The timeUnit.
      *
-     * @return ?TimeUnit
+     * @return TimeUnit
      */
-    public static function sampleTimeUnit(): ?TimeUnit {
+    public static function sampleTimeUnit(): TimeUnit {
         return TimeUnit::sample(); /*enum*/
     }
 
     /**
      * Array of objects that define fields to aggregate.
      *
-     * @param ?array $value
+     * @param array $value
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public static function fromAggregate(?array $value): ?array {
-        if (!is_null($value)) {
-            return  array_map(function ($value) {
-                return AggregatedFieldDef::from($value); /*class*/
-            }, $value);
-        } else {
-            return  null;
-        }
+    public static function fromAggregate(array $value): array {
+        return  array_map(function ($value) {
+            return AggregatedFieldDef::from($value); /*class*/
+        }, $value);
     }
 
     /**
      * Array of objects that define fields to aggregate.
      *
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function toAggregate(): ?array {
+    public function toAggregate(): array {
         if (Transform::validateAggregate($this->aggregate))  {
-            if (!is_null($this->aggregate)) {
-                return array_map(function ($value) {
-                    return $value->to(); /*class*/
-                }, $this->aggregate);
-            } else {
-                return  null;
-            }
+            return array_map(function ($value) {
+                return $value->to(); /*class*/
+            }, $this->aggregate);
         }
         throw new Exception('never get to this Transform::aggregate');
     }
@@ -74207,19 +73615,17 @@ class Transform {
     /**
      * Array of objects that define fields to aggregate.
      *
-     * @param array|null
+     * @param array
      * @return bool
      * @throws Exception
      */
-    public static function validateAggregate(?array $value): bool {
-        if (!is_null($value)) {
-            if (!is_array($value)) {
-                throw new Exception("Attribute Error:Transform::aggregate");
-            }
-            array_walk($value, function($value_v) {
-                $value_v->validate();
-            });
+    public static function validateAggregate(array $value): bool {
+        if (!is_array($value)) {
+            throw new Exception("Attribute Error:Transform::aggregate");
         }
+        array_walk($value, function($value_v) {
+            $value_v->validate();
+        });
         return true;
     }
 
@@ -74227,9 +73633,9 @@ class Transform {
      * Array of objects that define fields to aggregate.
      *
      * @throws Exception
-     * @return ?array
+     * @return array
      */
-    public function getAggregate(): ?array {
+    public function getAggregate(): array {
         if (Transform::validateAggregate($this->aggregate))  {
             return $this->aggregate;
         }
@@ -74239,9 +73645,9 @@ class Transform {
     /**
      * Array of objects that define fields to aggregate.
      *
-     * @return ?array
+     * @return array
      */
-    public static function sampleAggregate(): ?array {
+    public static function sampleAggregate(): array {
         return  array(
             AggregatedFieldDef::sample() /*40:*/
         ); /* 40:aggregate*/
diff --git a/head/schema-pike/test/inputs/schema/required-in-any-of.schema/default/TopLevel.pmod b/head/schema-pike/test/inputs/schema/required-in-any-of.schema/default/TopLevel.pmod
new file mode 100644
index 0000000..394aa2e
--- /dev/null
+++ b/head/schema-pike/test/inputs/schema/required-in-any-of.schema/default/TopLevel.pmod
@@ -0,0 +1,56 @@
+// This source has been automatically generated by quicktype.
+// ( https://github.com/quicktype/quicktype )
+//
+// To use this code, simply import it into your project as a Pike module.
+// To JSON-encode your object, you can pass it to `Standards.JSON.encode`
+// or call `encode_json` on it.
+//
+// To decode a JSON string, first pass it to `Standards.JSON.decode`,
+// and then pass the result to `<YourClass>_from_JSON`.
+// It will return an instance of <YourClass>.
+// Bear in mind that these functions have unexpected behavior,
+// and will likely throw an error, if the JSON string does not
+// match the expected interface, even if the JSON itself is valid.
+
+class TopLevel {
+    Anyof anyof; // json: "anyof"
+
+    string encode_json() {
+        mapping(string:mixed) json = ([
+            "anyof" : anyof,
+        ]);
+
+        return Standards.JSON.encode(json);
+    }
+}
+
+TopLevel TopLevel_from_JSON(mixed json) {
+    TopLevel retval = TopLevel();
+
+    retval.anyof = json["anyof"];
+
+    return retval;
+}
+
+class Anyof {
+    string       name; // json: "name"
+    mixed|string size; // json: "size"
+
+    string encode_json() {
+        mapping(string:mixed) json = ([
+            "name" : name,
+            "size" : size,
+        ]);
+
+        return Standards.JSON.encode(json);
+    }
+}
+
+Anyof Anyof_from_JSON(mixed json) {
+    Anyof retval = Anyof();
+
+    retval.name = json["name"];
+    retval.size = json["size"];
+
+    return retval;
+}
diff --git a/base/schema-pike/test/inputs/schema/vega-lite.schema/default/TopLevel.pmod b/head/schema-pike/test/inputs/schema/vega-lite.schema/default/TopLevel.pmod
index 141c32f..0550032 100644
--- a/base/schema-pike/test/inputs/schema/vega-lite.schema/default/TopLevel.pmod
+++ b/head/schema-pike/test/inputs/schema/vega-lite.schema/default/TopLevel.pmod
@@ -19,7 +19,7 @@ class TopLevel {
     Config|mixed                       config;      // json: "config"
     Data|mixed                         data;        // json: "data"
     mixed|string                       description; // json: "description"
-    EncodingWithFacet|mixed            encoding;    // json: "encoding"
+    EncodingWithFacet                  encoding;    // json: "encoding"
     float|mixed                        height;      // json: "height"
     AnyMark                            mark;        // json: "mark"
     mixed|string                       name;        // json: "name"
@@ -29,13 +29,13 @@ class TopLevel {
     Title                              title;       // json: "title"
     array(Transform)|mixed             transform;   // json: "transform"
     float|mixed                        width;       // json: "width"
-    array(LayerSpec)|mixed             layer;       // json: "layer"
+    array(LayerSpec)                   layer;       // json: "layer"
     Resolve|mixed                      resolve;     // json: "resolve"
-    FacetMapping|mixed                 facet;       // json: "facet"
-    Spec|mixed                         spec;        // json: "spec"
-    Repeat|mixed                       repeat;      // json: "repeat"
-    array(Spec)|mixed                  vconcat;     // json: "vconcat"
-    array(Spec)|mixed                  hconcat;     // json: "hconcat"
+    FacetMapping                       facet;       // json: "facet"
+    Spec                               spec;        // json: "spec"
+    Repeat                             repeat;      // json: "repeat"
+    array(Spec)                        vconcat;     // json: "vconcat"
+    array(Spec)                        hconcat;     // json: "hconcat"
 
     string encode_json() {
         mapping(string:mixed) json = ([
@@ -1225,7 +1225,7 @@ RangeConfigValue RangeConfigValue_from_JSON(mixed json) {
 class VgScheme {
     float|mixed        count;  // json: "count"
     array(float)|mixed extent; // json: "extent"
-    mixed|string       scheme; // json: "scheme"
+    string             scheme; // json: "scheme"
     float|mixed        step;   // json: "step"
 
     string encode_json() {
@@ -1597,12 +1597,12 @@ SingleSelectionConfig SingleSelectionConfig_from_JSON(mixed json) {
 }
 
 class VgBinding {
-    mixed|string        element; // json: "element"
-    string              input;   // json: "input"
-    array(string)|mixed options; // json: "options"
-    float|mixed         max;     // json: "max"
-    float|mixed         min;     // json: "min"
-    float|mixed         step;    // json: "step"
+    mixed|string  element; // json: "element"
+    string        input;   // json: "input"
+    array(string) options; // json: "options"
+    float|mixed   max;     // json: "max"
+    float|mixed   min;     // json: "min"
+    float|mixed   step;    // json: "step"
 
     string encode_json() {
         mapping(string:mixed) json = ([
@@ -2079,9 +2079,9 @@ ViewConfig ViewConfig_from_JSON(mixed json) {
 // Secondary data source to lookup in.
 class Data {
     DataFormat|mixed format; // json: "format"
-    mixed|string     url;    // json: "url"
+    string           url;    // json: "url"
     Values           values; // json: "values"
-    mixed|string     name;   // json: "name"
+    string           name;   // json: "name"
 
     string encode_json() {
         mapping(string:mixed) json = ([
@@ -2281,16 +2281,16 @@ EncodingWithFacet EncodingWithFacet_from_JSON(mixed json) {
 // value: ...,
 // }
 class MarkPropDefWithCondition {
-    AggregateOp|mixed                 aggregate; // json: "aggregate"
-    Bin                               bin;       // json: "bin"
-    ColorCondition                    condition; // json: "condition"
-    Field                             field;     // json: "field"
-    Legend|mixed                      legend;    // json: "legend"
-    Scale|mixed                       scale;     // json: "scale"
-    SortUnion                         sort;      // json: "sort"
-    TimeUnit|mixed                    time_unit; // json: "timeUnit"
-    Type|mixed                        type;      // json: "type"
-    ConditionalPredicateValueDefValue value;     // json: "value"
+    AggregateOp|mixed aggregate; // json: "aggregate"
+    ColorBin          bin;       // json: "bin"
+    ColorCondition    condition; // json: "condition"
+    Field             field;     // json: "field"
+    Legend|mixed      legend;    // json: "legend"
+    Scale|mixed       scale;     // json: "scale"
+    SortUnion         sort;      // json: "sort"
+    TimeUnit|mixed    time_unit; // json: "timeUnit"
+    Type              type;      // json: "type"
+    ColorValue        value;     // json: "value"
 
     string encode_json() {
         mapping(string:mixed) json = ([
@@ -2351,9 +2351,9 @@ enum AggregateOp {
     VARIANCEP = "variancep", // json: "variancep"
 }
 
-typedef BinParams|bool Bin;
+typedef BinParams|bool ColorBin;
 
-Bin Bin_from_JSON(mixed json) {
+ColorBin ColorBin_from_JSON(mixed json) {
     return json;
 }
 
@@ -2406,9 +2406,9 @@ ColorCondition ColorCondition_from_JSON(mixed json) {
 }
 
 class ConditionalValueDef {
-    ConditionalValueDefLogicalOperandPredicate test;      // json: "test"
-    ConditionalValueDefValue                   value;     // json: "value"
-    ConditionalValueDefSelectionOperand        selection; // json: "selection"
+    LogicalOperandPredicate  test;      // json: "test"
+    ConditionalValueDefValue value;     // json: "value"
+    SelectionOperand         selection; // json: "selection"
 
     string encode_json() {
         mapping(string:mixed) json = ([
@@ -2431,20 +2431,10 @@ ConditionalValueDef ConditionalValueDef_from_JSON(mixed json) {
     return retval;
 }
 
-// Filter using a selection name.
-//
-// A [selection name](selection.html), or a series of [composed
-// selections](selection.html#compose).
-typedef string|Selection SelectionOperandElement;
-
-SelectionOperandElement SelectionOperandElement_from_JSON(mixed json) {
-    return json;
-}
-
 class Selection {
-    ConditionalValueDefSelectionOperand  not; // json: "not"
-    array(SelectionOperandElement)|mixed and; // json: "and"
-    array(SelectionOperandElement)|mixed or;  // json: "or"
+    SelectionOperand        not; // json: "not"
+    array(SelectionOperand) and; // json: "and"
+    array(SelectionOperand) or;  // json: "or"
 
     string encode_json() {
         mapping(string:mixed) json = ([
@@ -2471,36 +2461,22 @@ Selection Selection_from_JSON(mixed json) {
 //
 // A [selection name](selection.html), or a series of [composed
 // selections](selection.html#compose).
-typedef string|Selection ConditionalValueDefSelectionOperand;
+typedef string|Selection SelectionOperand;
 
-ConditionalValueDefSelectionOperand ConditionalValueDefSelectionOperand_from_JSON(mixed json) {
-    return json;
-}
-
-// The `filter` property must be one of the predicate definitions:
-// (1) an [expression](types.html#expression) string,
-// where `datum` can be used to refer to the current data object;
-// (2) one of the field predicates: [equal predicate](filter.html#equal-predicate);
-// [range predicate](filter.html#range-predicate), [one-of
-// predicate](filter.html#one-of-predicate);
-// (3) a [selection predicate](filter.html#selection-predicate);
-// or (4) a logical operand that combines (1), (2), or (3).
-typedef Predicate|string LogicalOperandPredicateElement;
-
-LogicalOperandPredicateElement LogicalOperandPredicateElement_from_JSON(mixed json) {
+SelectionOperand SelectionOperand_from_JSON(mixed json) {
     return json;
 }
 
 class Predicate {
-    ConditionalValueDefLogicalOperandPredicate  not;       // json: "not"
-    array(LogicalOperandPredicateElement)|mixed and;       // json: "and"
-    array(LogicalOperandPredicateElement)|mixed or;        // json: "or"
-    EqualUnion                                  equal;     // json: "equal"
-    mixed|string                                field;     // json: "field"
-    TimeUnit|mixed                              time_unit; // json: "timeUnit"
-    array(RangeElement)|mixed                   range;     // json: "range"
-    array(OneOfElement)|mixed                   one_of;    // json: "oneOf"
-    ConditionalValueDefSelectionOperand         selection; // json: "selection"
+    LogicalOperandPredicate        not;       // json: "not"
+    array(LogicalOperandPredicate) and;       // json: "and"
+    array(LogicalOperandPredicate) or;        // json: "or"
+    Equal                          equal;     // json: "equal"
+    string                         field;     // json: "field"
+    TimeUnit|mixed                 time_unit; // json: "timeUnit"
+    array(RangeElement)            range;     // json: "range"
+    array(Equal)                   one_of;    // json: "oneOf"
+    SelectionOperand               selection; // json: "selection"
 
     string encode_json() {
         mapping(string:mixed) json = ([
@@ -2543,16 +2519,16 @@ Predicate Predicate_from_JSON(mixed json) {
 // predicate](filter.html#one-of-predicate);
 // (3) a [selection predicate](filter.html#selection-predicate);
 // or (4) a logical operand that combines (1), (2), or (3).
-typedef Predicate|string ConditionalValueDefLogicalOperandPredicate;
+typedef Predicate|string LogicalOperandPredicate;
 
-ConditionalValueDefLogicalOperandPredicate ConditionalValueDefLogicalOperandPredicate_from_JSON(mixed json) {
+LogicalOperandPredicate LogicalOperandPredicate_from_JSON(mixed json) {
     return json;
 }
 
 // The value that the field should be equal to.
-typedef bool|DateTime|float|string EqualUnion;
+typedef bool|DateTime|float|string Equal;
 
-EqualUnion EqualUnion_from_JSON(mixed json) {
+Equal Equal_from_JSON(mixed json) {
     return json;
 }
 
@@ -2627,13 +2603,6 @@ Month Month_from_JSON(mixed json) {
     return json;
 }
 
-// The value that the field should be equal to.
-typedef bool|DateTime|float|string OneOfElement;
-
-OneOfElement OneOfElement_from_JSON(mixed json) {
-    return json;
-}
-
 typedef DateTime|float RangeElement;
 
 RangeElement RangeElement_from_JSON(mixed json) {
@@ -2698,17 +2667,17 @@ ConditionalValueDefValue ConditionalValueDefValue_from_JSON(mixed json) {
 }
 
 class ConditionalPredicateMarkPropFieldDefClass {
-    ConditionalValueDefLogicalOperandPredicate test;      // json: "test"
-    ConditionalPredicateValueDefValue          value;     // json: "value"
-    ConditionalValueDefSelectionOperand        selection; // json: "selection"
-    AggregateOp|mixed                          aggregate; // json: "aggregate"
-    Bin                                        bin;       // json: "bin"
-    Field                                      field;     // json: "field"
-    Legend|mixed                               legend;    // json: "legend"
-    Scale|mixed                                scale;     // json: "scale"
-    SortUnion                                  sort;      // json: "sort"
-    TimeUnit|mixed                             time_unit; // json: "timeUnit"
-    Type|mixed                                 type;      // json: "type"
+    LogicalOperandPredicate  test;      // json: "test"
+    ConditionalValueDefValue value;     // json: "value"
+    SelectionOperand         selection; // json: "selection"
+    AggregateOp|mixed        aggregate; // json: "aggregate"
+    ColorBin                 bin;       // json: "bin"
+    Field                    field;     // json: "field"
+    Legend|mixed             legend;    // json: "legend"
+    Scale|mixed              scale;     // json: "scale"
+    SortUnion                sort;      // json: "sort"
+    TimeUnit|mixed           time_unit; // json: "timeUnit"
+    Type                     type;      // json: "type"
 
     string encode_json() {
         mapping(string:mixed) json = ([
@@ -2921,7 +2890,7 @@ Scale Scale_from_JSON(mixed json) {
 //
 // The `selection` property can be used to [interactively
 // determine](selection.html#scale-domains) the scale domain.
-typedef DomainClass|Domain|array(OneOfElement) DomainUnion;
+typedef DomainClass|Domain|array(Equal) DomainUnion;
 
 DomainUnion DomainUnion_from_JSON(mixed json) {
     return json;
@@ -3195,9 +3164,9 @@ enum Type {
 // `0` to `1` for opacity).
 //
 // A constant value in visual domain.
-typedef bool|float|string ConditionalPredicateValueDefValue;
+typedef bool|float|string ColorValue;
 
-ConditionalPredicateValueDefValue ConditionalPredicateValueDefValue_from_JSON(mixed json) {
+ColorValue ColorValue_from_JSON(mixed json) {
     return json;
 }
 
@@ -3206,7 +3175,7 @@ ConditionalPredicateValueDefValue ConditionalPredicateValueDefValue_from_JSON(mi
 // Vertical facets for trellis plots.
 class FacetFieldDef {
     AggregateOp|mixed aggregate; // json: "aggregate"
-    Bin               bin;       // json: "bin"
+    ColorBin          bin;       // json: "bin"
     Field             field;     // json: "field"
     Header|mixed      header;    // json: "header"
     SortEnum|mixed    sort;      // json: "sort"
@@ -3280,7 +3249,7 @@ Detail Detail_from_JSON(mixed json) {
 // Definition object for a data field, its type and transformation of an encoding channel.
 class FieldDef {
     AggregateOp|mixed aggregate; // json: "aggregate"
-    Bin               bin;       // json: "bin"
+    ColorBin          bin;       // json: "bin"
     Field             field;     // json: "field"
     TimeUnit|mixed    time_unit; // json: "timeUnit"
     Type              type;      // json: "type"
@@ -3325,13 +3294,13 @@ FieldDef FieldDef_from_JSON(mixed json) {
 // value: ...,
 // }
 class DefWithCondition {
-    AggregateOp|mixed                 aggregate; // json: "aggregate"
-    Bin                               bin;       // json: "bin"
-    HrefCondition                     condition; // json: "condition"
-    Field                             field;     // json: "field"
-    TimeUnit|mixed                    time_unit; // json: "timeUnit"
-    Type|mixed                        type;      // json: "type"
-    ConditionalPredicateValueDefValue value;     // json: "value"
+    AggregateOp|mixed aggregate; // json: "aggregate"
+    ColorBin          bin;       // json: "bin"
+    HrefCondition     condition; // json: "condition"
+    Field             field;     // json: "field"
+    TimeUnit|mixed    time_unit; // json: "timeUnit"
+    Type              type;      // json: "type"
+    ColorValue        value;     // json: "value"
 
     string encode_json() {
         mapping(string:mixed) json = ([
@@ -3369,14 +3338,14 @@ HrefCondition HrefCondition_from_JSON(mixed json) {
 }
 
 class ConditionalPredicateFieldDefClass {
-    ConditionalValueDefLogicalOperandPredicate test;      // json: "test"
-    ConditionalPredicateValueDefValue          value;     // json: "value"
-    ConditionalValueDefSelectionOperand        selection; // json: "selection"
-    AggregateOp|mixed                          aggregate; // json: "aggregate"
-    Bin                                        bin;       // json: "bin"
-    Field                                      field;     // json: "field"
-    TimeUnit|mixed                             time_unit; // json: "timeUnit"
-    Type|mixed                                 type;      // json: "type"
+    LogicalOperandPredicate  test;      // json: "test"
+    ConditionalValueDefValue value;     // json: "value"
+    SelectionOperand         selection; // json: "selection"
+    AggregateOp|mixed        aggregate; // json: "aggregate"
+    ColorBin                 bin;       // json: "bin"
+    Field                    field;     // json: "field"
+    TimeUnit|mixed           time_unit; // json: "timeUnit"
+    Type                     type;      // json: "type"
 
     string encode_json() {
         mapping(string:mixed) json = ([
@@ -3417,7 +3386,7 @@ Order Order_from_JSON(mixed json) {
 
 class OrderFieldDef {
     AggregateOp|mixed aggregate; // json: "aggregate"
-    Bin               bin;       // json: "bin"
+    ColorBin          bin;       // json: "bin"
     Field             field;     // json: "field"
     SortEnum|mixed    sort;      // json: "sort"
     TimeUnit|mixed    time_unit; // json: "timeUnit"
@@ -3467,14 +3436,14 @@ OrderFieldDef OrderFieldDef_from_JSON(mixed json) {
 // value: ...,
 // }
 class TextDefWithCondition {
-    AggregateOp|mixed                 aggregate; // json: "aggregate"
-    Bin                               bin;       // json: "bin"
-    TextCondition                     condition; // json: "condition"
-    Field                             field;     // json: "field"
-    mixed|string                      format;    // json: "format"
-    TimeUnit|mixed                    time_unit; // json: "timeUnit"
-    Type|mixed                        type;      // json: "type"
-    ConditionalPredicateValueDefValue value;     // json: "value"
+    AggregateOp|mixed aggregate; // json: "aggregate"
+    ColorBin          bin;       // json: "bin"
+    TextCondition     condition; // json: "condition"
+    Field             field;     // json: "field"
+    mixed|string      format;    // json: "format"
+    TimeUnit|mixed    time_unit; // json: "timeUnit"
+    Type              type;      // json: "type"
+    ColorValue        value;     // json: "value"
 
     string encode_json() {
         mapping(string:mixed) json = ([
@@ -3514,15 +3483,15 @@ TextCondition TextCondition_from_JSON(mixed json) {
 }
 
 class ConditionalPredicateTextFieldDefClass {
-    ConditionalValueDefLogicalOperandPredicate test;      // json: "test"
-    ConditionalPredicateValueDefValue          value;     // json: "value"
-    ConditionalValueDefSelectionOperand        selection; // json: "selection"
-    AggregateOp|mixed                          aggregate; // json: "aggregate"
-    Bin                                        bin;       // json: "bin"
-    Field                                      field;     // json: "field"
-    mixed|string                               format;    // json: "format"
-    TimeUnit|mixed                             time_unit; // json: "timeUnit"
-    Type|mixed                                 type;      // json: "type"
+    LogicalOperandPredicate  test;      // json: "test"
+    ConditionalValueDefValue value;     // json: "value"
+    SelectionOperand         selection; // json: "selection"
+    AggregateOp|mixed        aggregate; // json: "aggregate"
+    ColorBin                 bin;       // json: "bin"
+    Field                    field;     // json: "field"
+    mixed|string             format;    // json: "format"
+    TimeUnit|mixed           time_unit; // json: "timeUnit"
+    Type                     type;      // json: "type"
 
     string encode_json() {
         mapping(string:mixed) json = ([
@@ -3563,16 +3532,16 @@ ConditionalPredicateTextFieldDefClass ConditionalPredicateTextFieldDefClass_from
 //
 // Definition object for a constant value of an encoding channel.
 class XClass {
-    AggregateOp|mixed                 aggregate; // json: "aggregate"
-    Axis|mixed                        axis;      // json: "axis"
-    Bin                               bin;       // json: "bin"
-    Field                             field;     // json: "field"
-    Scale|mixed                       scale;     // json: "scale"
-    SortUnion                         sort;      // json: "sort"
-    StackOffset|mixed                 stack;     // json: "stack"
-    TimeUnit|mixed                    time_unit; // json: "timeUnit"
-    Type|mixed                        type;      // json: "type"
-    ConditionalPredicateValueDefValue value;     // json: "value"
+    AggregateOp|mixed        aggregate; // json: "aggregate"
+    Axis|mixed               axis;      // json: "axis"
+    ColorBin                 bin;       // json: "bin"
+    Field                    field;     // json: "field"
+    Scale|mixed              scale;     // json: "scale"
+    SortUnion                sort;      // json: "sort"
+    StackOffset|mixed        stack;     // json: "stack"
+    TimeUnit|mixed           time_unit; // json: "timeUnit"
+    Type                     type;      // json: "type"
+    ConditionalValueDefValue value;     // json: "value"
 
     string encode_json() {
         mapping(string:mixed) json = ([
@@ -3706,12 +3675,12 @@ AxisValue AxisValue_from_JSON(mixed json) {
 //
 // Definition object for a constant value of an encoding channel.
 class X2Class {
-    AggregateOp|mixed                 aggregate; // json: "aggregate"
-    Bin                               bin;       // json: "bin"
-    Field                             field;     // json: "field"
-    TimeUnit|mixed                    time_unit; // json: "timeUnit"
-    Type|mixed                        type;      // json: "type"
-    ConditionalPredicateValueDefValue value;     // json: "value"
+    AggregateOp|mixed        aggregate; // json: "aggregate"
+    ColorBin                 bin;       // json: "bin"
+    Field                    field;     // json: "field"
+    TimeUnit|mixed           time_unit; // json: "timeUnit"
+    Type                     type;      // json: "type"
+    ConditionalValueDefValue value;     // json: "value"
 
     string encode_json() {
         mapping(string:mixed) json = ([
@@ -3770,21 +3739,21 @@ class Spec {
     Data|mixed                         data;        // json: "data"
     mixed|string                       description; // json: "description"
     float|mixed                        height;      // json: "height"
-    array(LayerSpec)|mixed             layer;       // json: "layer"
+    array(LayerSpec)                   layer;       // json: "layer"
     mixed|string                       name;        // json: "name"
     Resolve|mixed                      resolve;     // json: "resolve"
     Title                              title;       // json: "title"
     array(Transform)|mixed             transform;   // json: "transform"
     float|mixed                        width;       // json: "width"
-    Encoding|mixed                     encoding;    // json: "encoding"
+    Encoding                           encoding;    // json: "encoding"
     AnyMark                            mark;        // json: "mark"
     Projection|mixed                   projection;  // json: "projection"
     mapping(string:SelectionDef)|mixed selection;   // json: "selection"
-    FacetMapping|mixed                 facet;       // json: "facet"
-    Spec|mixed                         spec;        // json: "spec"
-    Repeat|mixed                       repeat;      // json: "repeat"
-    array(Spec)|mixed                  vconcat;     // json: "vconcat"
-    array(Spec)|mixed                  hconcat;     // json: "hconcat"
+    FacetMapping                       facet;       // json: "facet"
+    Spec                               spec;        // json: "spec"
+    Repeat                             repeat;      // json: "repeat"
+    array(Spec)                        vconcat;     // json: "vconcat"
+    array(Spec)                        hconcat;     // json: "hconcat"
 
     string encode_json() {
         mapping(string:mixed) json = ([
@@ -3899,13 +3868,13 @@ class LayerSpec {
     Data|mixed                         data;        // json: "data"
     mixed|string                       description; // json: "description"
     float|mixed                        height;      // json: "height"
-    array(LayerSpec)|mixed             layer;       // json: "layer"
+    array(LayerSpec)                   layer;       // json: "layer"
     mixed|string                       name;        // json: "name"
     Resolve|mixed                      resolve;     // json: "resolve"
     Title                              title;       // json: "title"
     array(Transform)|mixed             transform;   // json: "transform"
     float|mixed                        width;       // json: "width"
-    Encoding|mixed                     encoding;    // json: "encoding"
+    Encoding                           encoding;    // json: "encoding"
     AnyMark                            mark;        // json: "mark"
     Projection|mixed                   projection;  // json: "projection"
     mapping(string:SelectionDef)|mixed selection;   // json: "selection"
@@ -4412,17 +4381,17 @@ TitleParams TitleParams_from_JSON(mixed json) {
 }
 
 class Transform {
-    ConditionalValueDefLogicalOperandPredicate filter;            // json: "filter"
-    Style                                      as;                // json: "as"
-    mixed|string                               calculate;         // json: "calculate"
-    mixed|string                               transform_default; // json: "default"
-    LookupData|mixed                           from;              // json: "from"
-    mixed|string                               lookup;            // json: "lookup"
-    Bin                                        bin;               // json: "bin"
-    mixed|string                               field;             // json: "field"
-    TimeUnit|mixed                             time_unit;         // json: "timeUnit"
-    array(AggregatedFieldDef)|mixed            aggregate;         // json: "aggregate"
-    array(string)|mixed                        groupby;           // json: "groupby"
+    LogicalOperandPredicate   filter;            // json: "filter"
+    Style                     as;                // json: "as"
+    string                    calculate;         // json: "calculate"
+    mixed|string              transform_default; // json: "default"
+    LookupData                from;              // json: "from"
+    string                    lookup;            // json: "lookup"
+    TransformBin              bin;               // json: "bin"
+    string                    field;             // json: "field"
+    TimeUnit                  time_unit;         // json: "timeUnit"
+    array(AggregatedFieldDef) aggregate;         // json: "aggregate"
+    array(string)|mixed       groupby;           // json: "groupby"
 
     string encode_json() {
         mapping(string:mixed) json = ([
@@ -4487,6 +4456,12 @@ AggregatedFieldDef AggregatedFieldDef_from_JSON(mixed json) {
     return retval;
 }
 
+typedef BinParams|bool TransformBin;
+
+TransformBin TransformBin_from_JSON(mixed json) {
+    return json;
+}
+
 // Secondary data reference.
 class LookupData {
     Data                data;   // json: "data"
diff --git a/head/schema-python/test/inputs/schema/required-in-any-of.schema/default/quicktype.py b/head/schema-python/test/inputs/schema/required-in-any-of.schema/default/quicktype.py
new file mode 100644
index 0000000..fbc8094
--- /dev/null
+++ b/head/schema-python/test/inputs/schema/required-in-any-of.schema/default/quicktype.py
@@ -0,0 +1,73 @@
+from dataclasses import dataclass
+from typing import Any, TypeVar, Type, cast
+
+
+T = TypeVar("T")
+
+
+def from_str(x: Any) -> str:
+    assert isinstance(x, str)
+    return x
+
+
+def from_none(x: Any) -> Any:
+    assert x is None
+    return x
+
+
+def from_union(fs, x):
+    for f in fs:
+        try:
+            return f(x)
+        except:
+            pass
+    assert False
+
+
+def to_class(c: Type[T], x: Any) -> dict:
+    assert isinstance(x, c)
+    return cast(Any, x).to_dict()
+
+
+@dataclass
+class Anyof:
+    name: str
+    size: str | None = None
+
+    @staticmethod
+    def from_dict(obj: Any) -> 'Anyof':
+        assert isinstance(obj, dict)
+        name = from_str(obj.get("name"))
+        size = from_union([from_str, from_none], obj.get("size"))
+        return Anyof(name, size)
+
+    def to_dict(self) -> dict:
+        result: dict = {}
+        result["name"] = from_str(self.name)
+        if self.size is not None:
+            result["size"] = from_union([from_str, from_none], self.size)
+        return result
+
+
+@dataclass
+class TopLevel:
+    anyof: Anyof
+
+    @staticmethod
+    def from_dict(obj: Any) -> 'TopLevel':
+        assert isinstance(obj, dict)
+        anyof = Anyof.from_dict(obj.get("anyof"))
+        return TopLevel(anyof)
+
+    def to_dict(self) -> dict:
+        result: dict = {}
+        result["anyof"] = to_class(Anyof, self.anyof)
+        return result
+
+
+def top_level_from_dict(s: Any) -> TopLevel:
+    return TopLevel.from_dict(s)
+
+
+def top_level_to_dict(x: TopLevel) -> Any:
+    return to_class(TopLevel, x)
diff --git a/base/schema-python/test/inputs/schema/vega-lite.schema/default/quicktype.py b/head/schema-python/test/inputs/schema/vega-lite.schema/default/quicktype.py
index af71a4d..7693cec 100644
--- a/base/schema-python/test/inputs/schema/vega-lite.schema/default/quicktype.py
+++ b/head/schema-python/test/inputs/schema/vega-lite.schema/default/quicktype.py
@@ -1866,28 +1866,27 @@ class ProjectionConfig:
 
 @dataclass
 class VGScheme:
+    scheme: str
     count: float | None = None
     extent: list[float] | None = None
-    scheme: str | None = None
     step: float | None = None
 
     @staticmethod
     def from_dict(obj: Any) -> 'VGScheme':
         assert isinstance(obj, dict)
+        scheme = from_str(obj.get("scheme"))
         count = from_union([from_float, from_none], obj.get("count"))
         extent = from_union([lambda x: from_list(from_float, x), from_none], obj.get("extent"))
-        scheme = from_union([from_str, from_none], obj.get("scheme"))
         step = from_union([from_float, from_none], obj.get("step"))
-        return VGScheme(count, extent, scheme, step)
+        return VGScheme(scheme, count, extent, step)
 
     def to_dict(self) -> dict:
         result: dict = {}
+        result["scheme"] = from_str(self.scheme)
         if self.count is not None:
             result["count"] = from_union([to_float, from_none], self.count)
         if self.extent is not None:
             result["extent"] = from_union([lambda x: from_list(to_float, x), from_none], self.extent)
-        if self.scheme is not None:
-            result["scheme"] = from_union([from_str, from_none], self.scheme)
         if self.step is not None:
             result["step"] = from_union([to_float, from_none], self.step)
         return result
@@ -2360,8 +2359,8 @@ class MultiSelectionConfig:
 @dataclass
 class VGBinding:
     input: str
+    options: list[str]
     element: str | None = None
-    options: list[str] | None = None
     max: float | None = None
     min: float | None = None
     step: float | None = None
@@ -2370,20 +2369,19 @@ class VGBinding:
     def from_dict(obj: Any) -> 'VGBinding':
         assert isinstance(obj, dict)
         input = from_str(obj.get("input"))
+        options = from_list(from_str, obj.get("options"))
         element = from_union([from_str, from_none], obj.get("element"))
-        options = from_union([lambda x: from_list(from_str, x), from_none], obj.get("options"))
         max = from_union([from_float, from_none], obj.get("max"))
         min = from_union([from_float, from_none], obj.get("min"))
         step = from_union([from_float, from_none], obj.get("step"))
-        return VGBinding(input, element, options, max, min, step)
+        return VGBinding(input, options, element, max, min, step)
 
     def to_dict(self) -> dict:
         result: dict = {}
         result["input"] = from_str(self.input)
+        result["options"] = from_list(from_str, self.options)
         if self.element is not None:
             result["element"] = from_union([from_str, from_none], self.element)
-        if self.options is not None:
-            result["options"] = from_union([lambda x: from_list(from_str, x), from_none], self.options)
         if self.max is not None:
             result["max"] = from_union([to_float, from_none], self.max)
         if self.min is not None:
@@ -3900,45 +3898,43 @@ class Data:
     
     Secondary data source to lookup in.
     """
-    format: DataFormat | None = None
-    """An object that specifies the format for parsing the data file.
-    
-    An object that specifies the format for parsing the data values.
-    
-    An object that specifies the format for parsing the data.
-    """
-    url: str | None = None
+    url: str
     """An URL from which to load the data set. Use the `format.type` property
     to ensure the loaded data is correctly parsed.
     """
-    values: list[float | bool | dict[str, Any] | str] | dict[str, Any] | str | None = None
+    values: list[float | bool | dict[str, Any] | str] | dict[str, Any] | str
     """The full data set, included inline. This can be an array of objects or primitive values
     or a string.
     Arrays of primitive values are ingested as objects with a `data` property. Strings are
     parsed according to the specified format type.
     """
-    name: str | None = None
+    name: str
     """Provide a placeholder name and bind data at runtime."""
 
+    format: DataFormat | None = None
+    """An object that specifies the format for parsing the data file.
+    
+    An object that specifies the format for parsing the data values.
+    
+    An object that specifies the format for parsing the data.
+    """
+
     @staticmethod
     def from_dict(obj: Any) -> 'Data':
         assert isinstance(obj, dict)
+        url = from_str(obj.get("url"))
+        values = from_union([lambda x: from_list(lambda x: from_union([from_float, from_bool, lambda x: from_dict(lambda x: x, x), from_str], x), x), lambda x: from_dict(lambda x: x, x), from_str], obj.get("values"))
+        name = from_str(obj.get("name"))
         format = from_union([DataFormat.from_dict, from_none], obj.get("format"))
-        url = from_union([from_str, from_none], obj.get("url"))
-        values = from_union([lambda x: from_list(lambda x: from_union([from_float, from_bool, lambda x: from_dict(lambda x: x, x), from_str], x), x), lambda x: from_dict(lambda x: x, x), from_str, from_none], obj.get("values"))
-        name = from_union([from_str, from_none], obj.get("name"))
-        return Data(format, url, values, name)
+        return Data(url, values, name, format)
 
     def to_dict(self) -> dict:
         result: dict = {}
+        result["url"] = from_str(self.url)
+        result["values"] = from_union([lambda x: from_list(lambda x: from_union([to_float, from_bool, lambda x: from_dict(lambda x: x, x), from_str], x), x), lambda x: from_dict(lambda x: x, x), from_str], self.values)
+        result["name"] = from_str(self.name)
         if self.format is not None:
             result["format"] = from_union([lambda x: to_class(DataFormat, x), from_none], self.format)
-        if self.url is not None:
-            result["url"] = from_union([from_str, from_none], self.url)
-        if self.values is not None:
-            result["values"] = from_union([lambda x: from_list(lambda x: from_union([to_float, from_bool, lambda x: from_dict(lambda x: x, x), from_str], x), x), lambda x: from_dict(lambda x: x, x), from_str, from_none], self.values)
-        if self.name is not None:
-            result["name"] = from_union([from_str, from_none], self.name)
         return result
 
 
@@ -4062,26 +4058,23 @@ class BinParams:
 
 @dataclass
 class Selection:
-    selection_not: 'Selection | str | None' = None
-    selection_and: 'list[Selection | str] | None' = None
-    selection_or: 'list[Selection | str] | None' = None
+    selection_not: 'Selection | str'
+    selection_and: list['Selection | str']
+    selection_or: list['Selection | str']
 
     @staticmethod
     def from_dict(obj: Any) -> 'Selection':
         assert isinstance(obj, dict)
-        selection_not = from_union([Selection.from_dict, from_str, from_none], obj.get("not"))
-        selection_and = from_union([lambda x: from_list(lambda x: from_union([Selection.from_dict, from_str], x), x), from_none], obj.get("and"))
-        selection_or = from_union([lambda x: from_list(lambda x: from_union([Selection.from_dict, from_str], x), x), from_none], obj.get("or"))
+        selection_not = from_union([Selection.from_dict, from_str], obj.get("not"))
+        selection_and = from_list(lambda x: from_union([Selection.from_dict, from_str], x), obj.get("and"))
+        selection_or = from_list(lambda x: from_union([Selection.from_dict, from_str], x), obj.get("or"))
         return Selection(selection_not, selection_and, selection_or)
 
     def to_dict(self) -> dict:
         result: dict = {}
-        if self.selection_not is not None:
-            result["not"] = from_union([lambda x: to_class(Selection, x), from_str, from_none], self.selection_not)
-        if self.selection_and is not None:
-            result["and"] = from_union([lambda x: from_list(lambda x: from_union([lambda x: to_class(Selection, x), from_str], x), x), from_none], self.selection_and)
-        if self.selection_or is not None:
-            result["or"] = from_union([lambda x: from_list(lambda x: from_union([lambda x: to_class(Selection, x), from_str], x), x), from_none], self.selection_or)
+        result["not"] = from_union([lambda x: to_class(Selection, x), from_str], self.selection_not)
+        result["and"] = from_list(lambda x: from_union([lambda x: to_class(Selection, x), from_str], x), self.selection_and)
+        result["or"] = from_list(lambda x: from_union([lambda x: to_class(Selection, x), from_str], x), self.selection_or)
         return result
 
 
@@ -4229,78 +4222,71 @@ class TimeUnit(Enum):
 
 @dataclass
 class Predicate:
-    predicate_not: 'Predicate | str | None' = None
-    predicate_and: 'list[Predicate | str] | None' = None
-    predicate_or: 'list[Predicate | str] | None' = None
-    equal: float | bool | DateTime | str | None = None
+    predicate_not: 'Predicate | str'
+    predicate_and: list['Predicate | str']
+    predicate_or: list['Predicate | str']
+    equal: float | bool | DateTime | str
     """The value that the field should be equal to."""
 
-    field: str | None = None
+    field: str
     """Field to be filtered.
     
     Field to be filtered
     """
-    time_unit: TimeUnit | None = None
-    """Time unit for the field to be filtered.
-    
-    time unit for the field to be filtered.
-    """
-    range: list[float | DateTime | None] | None = None
+    range: list[float | DateTime | None]
     """An array of inclusive minimum and maximum values
     for a field value of a data item to be included in the filtered data.
     """
-    one_of: list[float | bool | DateTime | str] | None = None
+    one_of: list[float | bool | DateTime | str]
     """A set of values that the `field`'s value should be a member of,
     for a data item included in the filtered data.
     """
-    selection: Selection | str | None = None
+    selection: Selection | str
     """Filter using a selection name."""
 
+    time_unit: TimeUnit | None = None
+    """Time unit for the field to be filtered.
+    
+    time unit for the field to be filtered.
+    """
+
     @staticmethod
     def from_dict(obj: Any) -> 'Predicate':
         assert isinstance(obj, dict)
-        predicate_not = from_union([Predicate.from_dict, from_str, from_none], obj.get("not"))
-        predicate_and = from_union([lambda x: from_list(lambda x: from_union([Predicate.from_dict, from_str], x), x), from_none], obj.get("and"))
-        predicate_or = from_union([lambda x: from_list(lambda x: from_union([Predicate.from_dict, from_str], x), x), from_none], obj.get("or"))
-        equal = from_union([from_float, from_bool, DateTime.from_dict, from_str, from_none], obj.get("equal"))
-        field = from_union([from_str, from_none], obj.get("field"))
+        predicate_not = from_union([Predicate.from_dict, from_str], obj.get("not"))
+        predicate_and = from_list(lambda x: from_union([Predicate.from_dict, from_str], x), obj.get("and"))
+        predicate_or = from_list(lambda x: from_union([Predicate.from_dict, from_str], x), obj.get("or"))
+        equal = from_union([from_float, from_bool, DateTime.from_dict, from_str], obj.get("equal"))
+        field = from_str(obj.get("field"))
+        range = from_list(lambda x: from_union([from_float, DateTime.from_dict, from_none], x), obj.get("range"))
+        one_of = from_list(lambda x: from_union([from_float, from_bool, DateTime.from_dict, from_str], x), obj.get("oneOf"))
+        selection = from_union([Selection.from_dict, from_str], obj.get("selection"))
         time_unit = from_union([TimeUnit, from_none], obj.get("timeUnit"))
-        range = from_union([lambda x: from_list(lambda x: from_union([from_float, DateTime.from_dict, from_none], x), x), from_none], obj.get("range"))
-        one_of = from_union([lambda x: from_list(lambda x: from_union([from_float, from_bool, DateTime.from_dict, from_str], x), x), from_none], obj.get("oneOf"))
-        selection = from_union([Selection.from_dict, from_str, from_none], obj.get("selection"))
-        return Predicate(predicate_not, predicate_and, predicate_or, equal, field, time_unit, range, one_of, selection)
+        return Predicate(predicate_not, predicate_and, predicate_or, equal, field, range, one_of, selection, time_unit)
 
     def to_dict(self) -> dict:
         result: dict = {}
-        if self.predicate_not is not None:
-            result["not"] = from_union([lambda x: to_class(Predicate, x), from_str, from_none], self.predicate_not)
-        if self.predicate_and is not None:
-            result["and"] = from_union([lambda x: from_list(lambda x: from_union([lambda x: to_class(Predicate, x), from_str], x), x), from_none], self.predicate_and)
-        if self.predicate_or is not None:
-            result["or"] = from_union([lambda x: from_list(lambda x: from_union([lambda x: to_class(Predicate, x), from_str], x), x), from_none], self.predicate_or)
-        if self.equal is not None:
-            result["equal"] = from_union([to_float, from_bool, lambda x: to_class(DateTime, x), from_str, from_none], self.equal)
-        if self.field is not None:
-            result["field"] = from_union([from_str, from_none], self.field)
+        result["not"] = from_union([lambda x: to_class(Predicate, x), from_str], self.predicate_not)
+        result["and"] = from_list(lambda x: from_union([lambda x: to_class(Predicate, x), from_str], x), self.predicate_and)
+        result["or"] = from_list(lambda x: from_union([lambda x: to_class(Predicate, x), from_str], x), self.predicate_or)
+        result["equal"] = from_union([to_float, from_bool, lambda x: to_class(DateTime, x), from_str], self.equal)
+        result["field"] = from_str(self.field)
+        result["range"] = from_list(lambda x: from_union([to_float, lambda x: to_class(DateTime, x), from_none], x), self.range)
+        result["oneOf"] = from_list(lambda x: from_union([to_float, from_bool, lambda x: to_class(DateTime, x), from_str], x), self.one_of)
+        result["selection"] = from_union([lambda x: to_class(Selection, x), from_str], self.selection)
         if self.time_unit is not None:
             result["timeUnit"] = from_union([lambda x: to_enum(TimeUnit, x), from_none], self.time_unit)
-        if self.range is not None:
-            result["range"] = from_union([lambda x: from_list(lambda x: from_union([to_float, lambda x: to_class(DateTime, x), from_none], x), x), from_none], self.range)
-        if self.one_of is not None:
-            result["oneOf"] = from_union([lambda x: from_list(lambda x: from_union([to_float, from_bool, lambda x: to_class(DateTime, x), from_str], x), x), from_none], self.one_of)
-        if self.selection is not None:
-            result["selection"] = from_union([lambda x: to_class(Selection, x), from_str, from_none], self.selection)
         return result
 
 
 @dataclass
 class ConditionalValueDef:
+    test: Predicate | str
     value: float | bool | str
     """A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
     `0` to `1` for opacity).
     """
-    test: Predicate | str | None = None
-    selection: Selection | str | None = None
+    selection: Selection | str
     """A [selection name](selection.html), or a series of [composed
     selections](selection.html#compose).
     """
@@ -4308,18 +4294,16 @@ class ConditionalValueDef:
     @staticmethod
     def from_dict(obj: Any) -> 'ConditionalValueDef':
         assert isinstance(obj, dict)
+        test = from_union([Predicate.from_dict, from_str], obj.get("test"))
         value = from_union([from_float, from_bool, from_str], obj.get("value"))
-        test = from_union([Predicate.from_dict, from_str, from_none], obj.get("test"))
-        selection = from_union([Selection.from_dict, from_str, from_none], obj.get("selection"))
-        return ConditionalValueDef(value, test, selection)
+        selection = from_union([Selection.from_dict, from_str], obj.get("selection"))
+        return ConditionalValueDef(test, value, selection)
 
     def to_dict(self) -> dict:
         result: dict = {}
+        result["test"] = from_union([lambda x: to_class(Predicate, x), from_str], self.test)
         result["value"] = from_union([to_float, from_bool, from_str], self.value)
-        if self.test is not None:
-            result["test"] = from_union([lambda x: to_class(Predicate, x), from_str, from_none], self.test)
-        if self.selection is not None:
-            result["selection"] = from_union([lambda x: to_class(Selection, x), from_str, from_none], self.selection)
+        result["selection"] = from_union([lambda x: to_class(Selection, x), from_str], self.selection)
         return result
 
 
@@ -4929,15 +4913,21 @@ class ConditionalPredicateValueDefType(Enum):
 
 @dataclass
 class ConditionalPredicateMarkPropFieldDefClass:
-    test: Predicate | str | None = None
-    value: float | bool | str | None = None
+    test: Predicate | str
+    value: float | bool | str
     """A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
     `0` to `1` for opacity).
     """
-    selection: Selection | str | None = None
+    selection: Selection | str
     """A [selection name](selection.html), or a series of [composed
     selections](selection.html#compose).
     """
+    type: ConditionalPredicateValueDefType
+    """The encoded field's type of measurement (`"quantitative"`, `"temporal"`, `"ordinal"`, or
+    `"nominal"`).
+    It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
+    [geographic projection](projection.html) is applied.
+    """
     aggregate: AggregateOp | None = None
     """Aggregation function for the field
     (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`).
@@ -4990,19 +4980,14 @@ class ConditionalPredicateMarkPropFieldDefClass:
     
     __Default value:__ `undefined` (None)
     """
-    type: ConditionalPredicateValueDefType | None = None
-    """The encoded field's type of measurement (`"quantitative"`, `"temporal"`, `"ordinal"`, or
-    `"nominal"`).
-    It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
-    [geographic projection](projection.html) is applied.
-    """
 
     @staticmethod
     def from_dict(obj: Any) -> 'ConditionalPredicateMarkPropFieldDefClass':
         assert isinstance(obj, dict)
-        test = from_union([Predicate.from_dict, from_str, from_none], obj.get("test"))
-        value = from_union([from_float, from_bool, from_str, from_none], obj.get("value"))
-        selection = from_union([Selection.from_dict, from_str, from_none], obj.get("selection"))
+        test = from_union([Predicate.from_dict, from_str], obj.get("test"))
+        value = from_union([from_float, from_bool, from_str], obj.get("value"))
+        selection = from_union([Selection.from_dict, from_str], obj.get("selection"))
+        type = ConditionalPredicateValueDefType(obj.get("type"))
         aggregate = from_union([AggregateOp, from_none], obj.get("aggregate"))
         bin = from_union([from_bool, BinParams.from_dict, from_none], obj.get("bin"))
         field = from_union([RepeatRef.from_dict, from_str, from_none], obj.get("field"))
@@ -5010,17 +4995,14 @@ class ConditionalPredicateMarkPropFieldDefClass:
         scale = from_union([Scale.from_dict, from_none], obj.get("scale"))
         sort = from_union([from_none, SortField.from_dict, SortEnum], obj.get("sort"))
         time_unit = from_union([TimeUnit, from_none], obj.get("timeUnit"))
-        type = from_union([ConditionalPredicateValueDefType, from_none], obj.get("type"))
-        return ConditionalPredicateMarkPropFieldDefClass(test, value, selection, aggregate, bin, field, legend, scale, sort, time_unit, type)
+        return ConditionalPredicateMarkPropFieldDefClass(test, value, selection, type, aggregate, bin, field, legend, scale, sort, time_unit)
 
     def to_dict(self) -> dict:
         result: dict = {}
-        if self.test is not None:
-            result["test"] = from_union([lambda x: to_class(Predicate, x), from_str, from_none], self.test)
-        if self.value is not None:
-            result["value"] = from_union([to_float, from_bool, from_str, from_none], self.value)
-        if self.selection is not None:
-            result["selection"] = from_union([lambda x: to_class(Selection, x), from_str, from_none], self.selection)
+        result["test"] = from_union([lambda x: to_class(Predicate, x), from_str], self.test)
+        result["value"] = from_union([to_float, from_bool, from_str], self.value)
+        result["selection"] = from_union([lambda x: to_class(Selection, x), from_str], self.selection)
+        result["type"] = to_enum(ConditionalPredicateValueDefType, self.type)
         if self.aggregate is not None:
             result["aggregate"] = from_union([lambda x: to_enum(AggregateOp, x), from_none], self.aggregate)
         if self.bin is not None:
@@ -5035,8 +5017,6 @@ class ConditionalPredicateMarkPropFieldDefClass:
             result["sort"] = from_union([from_none, lambda x: to_class(SortField, x), lambda x: to_enum(SortEnum, x)], self.sort)
         if self.time_unit is not None:
             result["timeUnit"] = from_union([lambda x: to_enum(TimeUnit, x), from_none], self.time_unit)
-        if self.type is not None:
-            result["type"] = from_union([lambda x: to_enum(ConditionalPredicateValueDefType, x), from_none], self.type)
         return result
 
 
@@ -5084,6 +5064,12 @@ class MarkPropDefWithCondition:
     value: ...,
     }
     """
+    type: ConditionalPredicateValueDefType
+    """The encoded field's type of measurement (`"quantitative"`, `"temporal"`, `"ordinal"`, or
+    `"nominal"`).
+    It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
+    [geographic projection](projection.html) is applied.
+    """
     aggregate: AggregateOp | None = None
     """Aggregation function for the field
     (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`).
@@ -5145,18 +5131,13 @@ class MarkPropDefWithCondition:
     
     __Default value:__ `undefined` (None)
     """
-    type: ConditionalPredicateValueDefType | None = None
-    """The encoded field's type of measurement (`"quantitative"`, `"temporal"`, `"ordinal"`, or
-    `"nominal"`).
-    It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
-    [geographic projection](projection.html) is applied.
-    """
     value: float | bool | str | None = None
     """A constant value in visual domain."""
 
     @staticmethod
     def from_dict(obj: Any) -> 'MarkPropDefWithCondition':
         assert isinstance(obj, dict)
+        type = ConditionalPredicateValueDefType(obj.get("type"))
         aggregate = from_union([AggregateOp, from_none], obj.get("aggregate"))
         bin = from_union([from_bool, BinParams.from_dict, from_none], obj.get("bin"))
         condition = from_union([ConditionalPredicateMarkPropFieldDefClass.from_dict, lambda x: from_list(ConditionalValueDef.from_dict, x), from_none], obj.get("condition"))
@@ -5165,12 +5146,12 @@ class MarkPropDefWithCondition:
         scale = from_union([Scale.from_dict, from_none], obj.get("scale"))
         sort = from_union([from_none, SortField.from_dict, SortEnum], obj.get("sort"))
         time_unit = from_union([TimeUnit, from_none], obj.get("timeUnit"))
-        type = from_union([ConditionalPredicateValueDefType, from_none], obj.get("type"))
         value = from_union([from_float, from_bool, from_str, from_none], obj.get("value"))
-        return MarkPropDefWithCondition(aggregate, bin, condition, field, legend, scale, sort, time_unit, type, value)
+        return MarkPropDefWithCondition(type, aggregate, bin, condition, field, legend, scale, sort, time_unit, value)
 
     def to_dict(self) -> dict:
         result: dict = {}
+        result["type"] = to_enum(ConditionalPredicateValueDefType, self.type)
         if self.aggregate is not None:
             result["aggregate"] = from_union([lambda x: to_enum(AggregateOp, x), from_none], self.aggregate)
         if self.bin is not None:
@@ -5187,8 +5168,6 @@ class MarkPropDefWithCondition:
             result["sort"] = from_union([from_none, lambda x: to_class(SortField, x), lambda x: to_enum(SortEnum, x)], self.sort)
         if self.time_unit is not None:
             result["timeUnit"] = from_union([lambda x: to_enum(TimeUnit, x), from_none], self.time_unit)
-        if self.type is not None:
-            result["type"] = from_union([lambda x: to_enum(ConditionalPredicateValueDefType, x), from_none], self.type)
         if self.value is not None:
             result["value"] = from_union([to_float, from_bool, from_str, from_none], self.value)
         return result
@@ -5399,15 +5378,21 @@ class FieldDef:
 
 @dataclass
 class ConditionalPredicateFieldDefClass:
-    test: Predicate | str | None = None
-    value: float | bool | str | None = None
+    test: Predicate | str
+    value: float | bool | str
     """A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
     `0` to `1` for opacity).
     """
-    selection: Selection | str | None = None
+    selection: Selection | str
     """A [selection name](selection.html), or a series of [composed
     selections](selection.html#compose).
     """
+    type: ConditionalPredicateValueDefType
+    """The encoded field's type of measurement (`"quantitative"`, `"temporal"`, `"ordinal"`, or
+    `"nominal"`).
+    It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
+    [geographic projection](projection.html) is applied.
+    """
     aggregate: AggregateOp | None = None
     """Aggregation function for the field
     (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`).
@@ -5439,34 +5424,26 @@ class ConditionalPredicateFieldDefClass:
     
     __Default value:__ `undefined` (None)
     """
-    type: ConditionalPredicateValueDefType | None = None
-    """The encoded field's type of measurement (`"quantitative"`, `"temporal"`, `"ordinal"`, or
-    `"nominal"`).
-    It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
-    [geographic projection](projection.html) is applied.
-    """
 
     @staticmethod
     def from_dict(obj: Any) -> 'ConditionalPredicateFieldDefClass':
         assert isinstance(obj, dict)
-        test = from_union([Predicate.from_dict, from_str, from_none], obj.get("test"))
-        value = from_union([from_float, from_bool, from_str, from_none], obj.get("value"))
-        selection = from_union([Selection.from_dict, from_str, from_none], obj.get("selection"))
+        test = from_union([Predicate.from_dict, from_str], obj.get("test"))
+        value = from_union([from_float, from_bool, from_str], obj.get("value"))
+        selection = from_union([Selection.from_dict, from_str], obj.get("selection"))
+        type = ConditionalPredicateValueDefType(obj.get("type"))
         aggregate = from_union([AggregateOp, from_none], obj.get("aggregate"))
         bin = from_union([from_bool, BinParams.from_dict, from_none], obj.get("bin"))
         field = from_union([RepeatRef.from_dict, from_str, from_none], obj.get("field"))
         time_unit = from_union([TimeUnit, from_none], obj.get("timeUnit"))
-        type = from_union([ConditionalPredicateValueDefType, from_none], obj.get("type"))
-        return ConditionalPredicateFieldDefClass(test, value, selection, aggregate, bin, field, time_unit, type)
+        return ConditionalPredicateFieldDefClass(test, value, selection, type, aggregate, bin, field, time_unit)
 
     def to_dict(self) -> dict:
         result: dict = {}
-        if self.test is not None:
-            result["test"] = from_union([lambda x: to_class(Predicate, x), from_str, from_none], self.test)
-        if self.value is not None:
-            result["value"] = from_union([to_float, from_bool, from_str, from_none], self.value)
-        if self.selection is not None:
-            result["selection"] = from_union([lambda x: to_class(Selection, x), from_str, from_none], self.selection)
+        result["test"] = from_union([lambda x: to_class(Predicate, x), from_str], self.test)
+        result["value"] = from_union([to_float, from_bool, from_str], self.value)
+        result["selection"] = from_union([lambda x: to_class(Selection, x), from_str], self.selection)
+        result["type"] = to_enum(ConditionalPredicateValueDefType, self.type)
         if self.aggregate is not None:
             result["aggregate"] = from_union([lambda x: to_enum(AggregateOp, x), from_none], self.aggregate)
         if self.bin is not None:
@@ -5475,8 +5452,6 @@ class ConditionalPredicateFieldDefClass:
             result["field"] = from_union([lambda x: to_class(RepeatRef, x), from_str, from_none], self.field)
         if self.time_unit is not None:
             result["timeUnit"] = from_union([lambda x: to_enum(TimeUnit, x), from_none], self.time_unit)
-        if self.type is not None:
-            result["type"] = from_union([lambda x: to_enum(ConditionalPredicateValueDefType, x), from_none], self.type)
         return result
 
 
@@ -5497,6 +5472,12 @@ class DefWithCondition:
     value: ...,
     }
     """
+    type: ConditionalPredicateValueDefType
+    """The encoded field's type of measurement (`"quantitative"`, `"temporal"`, `"ordinal"`, or
+    `"nominal"`).
+    It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
+    [geographic projection](projection.html) is applied.
+    """
     aggregate: AggregateOp | None = None
     """Aggregation function for the field
     (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`).
@@ -5537,29 +5518,24 @@ class DefWithCondition:
     
     __Default value:__ `undefined` (None)
     """
-    type: ConditionalPredicateValueDefType | None = None
-    """The encoded field's type of measurement (`"quantitative"`, `"temporal"`, `"ordinal"`, or
-    `"nominal"`).
-    It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
-    [geographic projection](projection.html) is applied.
-    """
     value: float | bool | str | None = None
     """A constant value in visual domain."""
 
     @staticmethod
     def from_dict(obj: Any) -> 'DefWithCondition':
         assert isinstance(obj, dict)
+        type = ConditionalPredicateValueDefType(obj.get("type"))
         aggregate = from_union([AggregateOp, from_none], obj.get("aggregate"))
         bin = from_union([from_bool, BinParams.from_dict, from_none], obj.get("bin"))
         condition = from_union([ConditionalPredicateFieldDefClass.from_dict, lambda x: from_list(ConditionalValueDef.from_dict, x), from_none], obj.get("condition"))
         field = from_union([RepeatRef.from_dict, from_str, from_none], obj.get("field"))
         time_unit = from_union([TimeUnit, from_none], obj.get("timeUnit"))
-        type = from_union([ConditionalPredicateValueDefType, from_none], obj.get("type"))
         value = from_union([from_float, from_bool, from_str, from_none], obj.get("value"))
-        return DefWithCondition(aggregate, bin, condition, field, time_unit, type, value)
+        return DefWithCondition(type, aggregate, bin, condition, field, time_unit, value)
 
     def to_dict(self) -> dict:
         result: dict = {}
+        result["type"] = to_enum(ConditionalPredicateValueDefType, self.type)
         if self.aggregate is not None:
             result["aggregate"] = from_union([lambda x: to_enum(AggregateOp, x), from_none], self.aggregate)
         if self.bin is not None:
@@ -5570,8 +5546,6 @@ class DefWithCondition:
             result["field"] = from_union([lambda x: to_class(RepeatRef, x), from_str, from_none], self.field)
         if self.time_unit is not None:
             result["timeUnit"] = from_union([lambda x: to_enum(TimeUnit, x), from_none], self.time_unit)
-        if self.type is not None:
-            result["type"] = from_union([lambda x: to_enum(ConditionalPredicateValueDefType, x), from_none], self.type)
         if self.value is not None:
             result["value"] = from_union([to_float, from_bool, from_str, from_none], self.value)
         return result
@@ -5649,15 +5623,21 @@ class OrderFieldDef:
 
 @dataclass
 class ConditionalPredicateTextFieldDefClass:
-    test: Predicate | str | None = None
-    value: float | bool | str | None = None
+    test: Predicate | str
+    value: float | bool | str
     """A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
     `0` to `1` for opacity).
     """
-    selection: Selection | str | None = None
+    selection: Selection | str
     """A [selection name](selection.html), or a series of [composed
     selections](selection.html#compose).
     """
+    type: ConditionalPredicateValueDefType
+    """The encoded field's type of measurement (`"quantitative"`, `"temporal"`, `"ordinal"`, or
+    `"nominal"`).
+    It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
+    [geographic projection](projection.html) is applied.
+    """
     aggregate: AggregateOp | None = None
     """Aggregation function for the field
     (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`).
@@ -5693,35 +5673,27 @@ class ConditionalPredicateTextFieldDefClass:
     
     __Default value:__ `undefined` (None)
     """
-    type: ConditionalPredicateValueDefType | None = None
-    """The encoded field's type of measurement (`"quantitative"`, `"temporal"`, `"ordinal"`, or
-    `"nominal"`).
-    It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
-    [geographic projection](projection.html) is applied.
-    """
 
     @staticmethod
     def from_dict(obj: Any) -> 'ConditionalPredicateTextFieldDefClass':
         assert isinstance(obj, dict)
-        test = from_union([Predicate.from_dict, from_str, from_none], obj.get("test"))
-        value = from_union([from_float, from_bool, from_str, from_none], obj.get("value"))
-        selection = from_union([Selection.from_dict, from_str, from_none], obj.get("selection"))
+        test = from_union([Predicate.from_dict, from_str], obj.get("test"))
+        value = from_union([from_float, from_bool, from_str], obj.get("value"))
+        selection = from_union([Selection.from_dict, from_str], obj.get("selection"))
+        type = ConditionalPredicateValueDefType(obj.get("type"))
         aggregate = from_union([AggregateOp, from_none], obj.get("aggregate"))
         bin = from_union([from_bool, BinParams.from_dict, from_none], obj.get("bin"))
         field = from_union([RepeatRef.from_dict, from_str, from_none], obj.get("field"))
         format = from_union([from_str, from_none], obj.get("format"))
         time_unit = from_union([TimeUnit, from_none], obj.get("timeUnit"))
-        type = from_union([ConditionalPredicateValueDefType, from_none], obj.get("type"))
-        return ConditionalPredicateTextFieldDefClass(test, value, selection, aggregate, bin, field, format, time_unit, type)
+        return ConditionalPredicateTextFieldDefClass(test, value, selection, type, aggregate, bin, field, format, time_unit)
 
     def to_dict(self) -> dict:
         result: dict = {}
-        if self.test is not None:
-            result["test"] = from_union([lambda x: to_class(Predicate, x), from_str, from_none], self.test)
-        if self.value is not None:
-            result["value"] = from_union([to_float, from_bool, from_str, from_none], self.value)
-        if self.selection is not None:
-            result["selection"] = from_union([lambda x: to_class(Selection, x), from_str, from_none], self.selection)
+        result["test"] = from_union([lambda x: to_class(Predicate, x), from_str], self.test)
+        result["value"] = from_union([to_float, from_bool, from_str], self.value)
+        result["selection"] = from_union([lambda x: to_class(Selection, x), from_str], self.selection)
+        result["type"] = to_enum(ConditionalPredicateValueDefType, self.type)
         if self.aggregate is not None:
             result["aggregate"] = from_union([lambda x: to_enum(AggregateOp, x), from_none], self.aggregate)
         if self.bin is not None:
@@ -5732,8 +5704,6 @@ class ConditionalPredicateTextFieldDefClass:
             result["format"] = from_union([from_str, from_none], self.format)
         if self.time_unit is not None:
             result["timeUnit"] = from_union([lambda x: to_enum(TimeUnit, x), from_none], self.time_unit)
-        if self.type is not None:
-            result["type"] = from_union([lambda x: to_enum(ConditionalPredicateValueDefType, x), from_none], self.type)
         return result
 
 
@@ -5756,6 +5726,12 @@ class TextDefWithCondition:
     value: ...,
     }
     """
+    type: ConditionalPredicateValueDefType
+    """The encoded field's type of measurement (`"quantitative"`, `"temporal"`, `"ordinal"`, or
+    `"nominal"`).
+    It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
+    [geographic projection](projection.html) is applied.
+    """
     aggregate: AggregateOp | None = None
     """Aggregation function for the field
     (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`).
@@ -5800,30 +5776,25 @@ class TextDefWithCondition:
     
     __Default value:__ `undefined` (None)
     """
-    type: ConditionalPredicateValueDefType | None = None
-    """The encoded field's type of measurement (`"quantitative"`, `"temporal"`, `"ordinal"`, or
-    `"nominal"`).
-    It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
-    [geographic projection](projection.html) is applied.
-    """
     value: float | bool | str | None = None
     """A constant value in visual domain."""
 
     @staticmethod
     def from_dict(obj: Any) -> 'TextDefWithCondition':
         assert isinstance(obj, dict)
+        type = ConditionalPredicateValueDefType(obj.get("type"))
         aggregate = from_union([AggregateOp, from_none], obj.get("aggregate"))
         bin = from_union([from_bool, BinParams.from_dict, from_none], obj.get("bin"))
         condition = from_union([ConditionalPredicateTextFieldDefClass.from_dict, lambda x: from_list(ConditionalValueDef.from_dict, x), from_none], obj.get("condition"))
         field = from_union([RepeatRef.from_dict, from_str, from_none], obj.get("field"))
         format = from_union([from_str, from_none], obj.get("format"))
         time_unit = from_union([TimeUnit, from_none], obj.get("timeUnit"))
-        type = from_union([ConditionalPredicateValueDefType, from_none], obj.get("type"))
         value = from_union([from_float, from_bool, from_str, from_none], obj.get("value"))
-        return TextDefWithCondition(aggregate, bin, condition, field, format, time_unit, type, value)
+        return TextDefWithCondition(type, aggregate, bin, condition, field, format, time_unit, value)
 
     def to_dict(self) -> dict:
         result: dict = {}
+        result["type"] = to_enum(ConditionalPredicateValueDefType, self.type)
         if self.aggregate is not None:
             result["aggregate"] = from_union([lambda x: to_enum(AggregateOp, x), from_none], self.aggregate)
         if self.bin is not None:
@@ -5836,8 +5807,6 @@ class TextDefWithCondition:
             result["format"] = from_union([from_str, from_none], self.format)
         if self.time_unit is not None:
             result["timeUnit"] = from_union([lambda x: to_enum(TimeUnit, x), from_none], self.time_unit)
-        if self.type is not None:
-            result["type"] = from_union([lambda x: to_enum(ConditionalPredicateValueDefType, x), from_none], self.type)
         if self.value is not None:
             result["value"] = from_union([to_float, from_bool, from_str, from_none], self.value)
         return result
@@ -6072,6 +6041,16 @@ class XClass:
     
     Definition object for a constant value of an encoding channel.
     """
+    type: ConditionalPredicateValueDefType
+    """The encoded field's type of measurement (`"quantitative"`, `"temporal"`, `"ordinal"`, or
+    `"nominal"`).
+    It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
+    [geographic projection](projection.html) is applied.
+    """
+    value: float | bool | str
+    """A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
+    `0` to `1` for opacity).
+    """
     aggregate: AggregateOp | None = None
     """Aggregation function for the field
     (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`).
@@ -6146,20 +6125,12 @@ class XClass:
     
     __Default value:__ `undefined` (None)
     """
-    type: ConditionalPredicateValueDefType | None = None
-    """The encoded field's type of measurement (`"quantitative"`, `"temporal"`, `"ordinal"`, or
-    `"nominal"`).
-    It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
-    [geographic projection](projection.html) is applied.
-    """
-    value: float | bool | str | None = None
-    """A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
-    `0` to `1` for opacity).
-    """
 
     @staticmethod
     def from_dict(obj: Any) -> 'XClass':
         assert isinstance(obj, dict)
+        type = ConditionalPredicateValueDefType(obj.get("type"))
+        value = from_union([from_float, from_bool, from_str], obj.get("value"))
         aggregate = from_union([AggregateOp, from_none], obj.get("aggregate"))
         axis = from_union([Axis.from_dict, from_none], obj.get("axis"))
         bin = from_union([from_bool, BinParams.from_dict, from_none], obj.get("bin"))
@@ -6168,12 +6139,12 @@ class XClass:
         sort = from_union([from_none, SortField.from_dict, SortEnum], obj.get("sort"))
         stack = from_union([StackOffset, from_none], obj.get("stack"))
         time_unit = from_union([TimeUnit, from_none], obj.get("timeUnit"))
-        type = from_union([ConditionalPredicateValueDefType, from_none], obj.get("type"))
-        value = from_union([from_float, from_bool, from_str, from_none], obj.get("value"))
-        return XClass(aggregate, axis, bin, field, scale, sort, stack, time_unit, type, value)
+        return XClass(type, value, aggregate, axis, bin, field, scale, sort, stack, time_unit)
 
     def to_dict(self) -> dict:
         result: dict = {}
+        result["type"] = to_enum(ConditionalPredicateValueDefType, self.type)
+        result["value"] = from_union([to_float, from_bool, from_str], self.value)
         if self.aggregate is not None:
             result["aggregate"] = from_union([lambda x: to_enum(AggregateOp, x), from_none], self.aggregate)
         if self.axis is not None:
@@ -6190,10 +6161,6 @@ class XClass:
             result["stack"] = from_union([lambda x: to_enum(StackOffset, x), from_none], self.stack)
         if self.time_unit is not None:
             result["timeUnit"] = from_union([lambda x: to_enum(TimeUnit, x), from_none], self.time_unit)
-        if self.type is not None:
-            result["type"] = from_union([lambda x: to_enum(ConditionalPredicateValueDefType, x), from_none], self.type)
-        if self.value is not None:
-            result["value"] = from_union([to_float, from_bool, from_str, from_none], self.value)
         return result
 
 
@@ -6207,6 +6174,16 @@ class X2Class:
     
     Definition object for a constant value of an encoding channel.
     """
+    type: ConditionalPredicateValueDefType
+    """The encoded field's type of measurement (`"quantitative"`, `"temporal"`, `"ordinal"`, or
+    `"nominal"`).
+    It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
+    [geographic projection](projection.html) is applied.
+    """
+    value: float | bool | str
+    """A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
+    `0` to `1` for opacity).
+    """
     aggregate: AggregateOp | None = None
     """Aggregation function for the field
     (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`).
@@ -6238,30 +6215,22 @@ class X2Class:
     
     __Default value:__ `undefined` (None)
     """
-    type: ConditionalPredicateValueDefType | None = None
-    """The encoded field's type of measurement (`"quantitative"`, `"temporal"`, `"ordinal"`, or
-    `"nominal"`).
-    It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
-    [geographic projection](projection.html) is applied.
-    """
-    value: float | bool | str | None = None
-    """A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
-    `0` to `1` for opacity).
-    """
 
     @staticmethod
     def from_dict(obj: Any) -> 'X2Class':
         assert isinstance(obj, dict)
+        type = ConditionalPredicateValueDefType(obj.get("type"))
+        value = from_union([from_float, from_bool, from_str], obj.get("value"))
         aggregate = from_union([AggregateOp, from_none], obj.get("aggregate"))
         bin = from_union([from_bool, BinParams.from_dict, from_none], obj.get("bin"))
         field = from_union([RepeatRef.from_dict, from_str, from_none], obj.get("field"))
         time_unit = from_union([TimeUnit, from_none], obj.get("timeUnit"))
-        type = from_union([ConditionalPredicateValueDefType, from_none], obj.get("type"))
-        value = from_union([from_float, from_bool, from_str, from_none], obj.get("value"))
-        return X2Class(aggregate, bin, field, time_unit, type, value)
+        return X2Class(type, value, aggregate, bin, field, time_unit)
 
     def to_dict(self) -> dict:
         result: dict = {}
+        result["type"] = to_enum(ConditionalPredicateValueDefType, self.type)
+        result["value"] = from_union([to_float, from_bool, from_str], self.value)
         if self.aggregate is not None:
             result["aggregate"] = from_union([lambda x: to_enum(AggregateOp, x), from_none], self.aggregate)
         if self.bin is not None:
@@ -6270,10 +6239,6 @@ class X2Class:
             result["field"] = from_union([lambda x: to_class(RepeatRef, x), from_str, from_none], self.field)
         if self.time_unit is not None:
             result["timeUnit"] = from_union([lambda x: to_enum(TimeUnit, x), from_none], self.time_unit)
-        if self.type is not None:
-            result["type"] = from_union([lambda x: to_enum(ConditionalPredicateValueDefType, x), from_none], self.type)
-        if self.value is not None:
-            result["value"] = from_union([to_float, from_bool, from_str, from_none], self.value)
         return result
 
 
@@ -7350,7 +7315,7 @@ class LookupData:
 
 @dataclass
 class Transform:
-    filter: Predicate | str | None = None
+    filter: Predicate | str
     """The `filter` property must be one of the predicate definitions:
     (1) an [expression](types.html#expression) string,
     where `datum` can be used to refer to the current data object;
@@ -7360,47 +7325,47 @@ class Transform:
     (3) a [selection predicate](filter.html#selection-predicate);
     or (4) a logical operand that combines (1), (2), or (3).
     """
-    transform_as: list[str] | str | None = None
-    """The field for storing the computed formula value.
-    
-    The field or fields for storing the computed formula value.
-    If `from.fields` is specified, the transform will use the same names for `as`.
-    If `from.fields` is not specified, `as` has to be a string and we put the whole object
-    into the data under the specified name.
-    
-    The output fields at which to write the start and end bin values.
-    
-    The output field to write the timeUnit value.
-    """
-    calculate: str | None = None
+    calculate: str
     """A [expression](types.html#expression) string. Use the variable `datum` to refer to the
     current data object.
     """
-    default: str | None = None
-    """The default value to use if lookup fails.
-    
-    __Default value:__ `null`
-    """
-    transform_from: LookupData | None = None
+    transform_from: LookupData
     """Secondary data reference."""
 
-    lookup: str | None = None
+    lookup: str
     """Key in primary data source."""
 
-    bin: bool | BinParams | None = None
+    bin: bool | BinParams
     """An object indicating bin properties, or simply `true` for using default bin parameters."""
 
-    field: str | None = None
+    field: str
     """The data field to bin.
     
     The data field to apply time unit.
     """
-    time_unit: TimeUnit | None = None
+    time_unit: TimeUnit
     """The timeUnit."""
 
-    aggregate: list[AggregatedFieldDef] | None = None
+    aggregate: list[AggregatedFieldDef]
     """Array of objects that define fields to aggregate."""
 
+    transform_as: list[str] | str | None = None
+    """The field for storing the computed formula value.
+    
+    The field or fields for storing the computed formula value.
+    If `from.fields` is specified, the transform will use the same names for `as`.
+    If `from.fields` is not specified, `as` has to be a string and we put the whole object
+    into the data under the specified name.
+    
+    The output fields at which to write the start and end bin values.
+    
+    The output field to write the timeUnit value.
+    """
+    default: str | None = None
+    """The default value to use if lookup fails.
+    
+    __Default value:__ `null`
+    """
     groupby: list[str] | None = None
     """The data fields to group by. If not specified, a single group containing all data objects
     will be used.
@@ -7409,41 +7374,33 @@ class Transform:
     @staticmethod
     def from_dict(obj: Any) -> 'Transform':
         assert isinstance(obj, dict)
-        filter = from_union([Predicate.from_dict, from_str, from_none], obj.get("filter"))
+        filter = from_union([Predicate.from_dict, from_str], obj.get("filter"))
+        calculate = from_str(obj.get("calculate"))
+        transform_from = LookupData.from_dict(obj.get("from"))
+        lookup = from_str(obj.get("lookup"))
+        bin = from_union([from_bool, BinParams.from_dict], obj.get("bin"))
+        field = from_str(obj.get("field"))
+        time_unit = TimeUnit(obj.get("timeUnit"))
+        aggregate = from_list(AggregatedFieldDef.from_dict, obj.get("aggregate"))
         transform_as = from_union([lambda x: from_list(from_str, x), from_str, from_none], obj.get("as"))
-        calculate = from_union([from_str, from_none], obj.get("calculate"))
         default = from_union([from_str, from_none], obj.get("default"))
-        transform_from = from_union([LookupData.from_dict, from_none], obj.get("from"))
-        lookup = from_union([from_str, from_none], obj.get("lookup"))
-        bin = from_union([from_bool, BinParams.from_dict, from_none], obj.get("bin"))
-        field = from_union([from_str, from_none], obj.get("field"))
-        time_unit = from_union([TimeUnit, from_none], obj.get("timeUnit"))
-        aggregate = from_union([lambda x: from_list(AggregatedFieldDef.from_dict, x), from_none], obj.get("aggregate"))
         groupby = from_union([lambda x: from_list(from_str, x), from_none], obj.get("groupby"))
-        return Transform(filter, transform_as, calculate, default, transform_from, lookup, bin, field, time_unit, aggregate, groupby)
+        return Transform(filter, calculate, transform_from, lookup, bin, field, time_unit, aggregate, transform_as, default, groupby)
 
     def to_dict(self) -> dict:
         result: dict = {}
-        if self.filter is not None:
-            result["filter"] = from_union([lambda x: to_class(Predicate, x), from_str, from_none], self.filter)
+        result["filter"] = from_union([lambda x: to_class(Predicate, x), from_str], self.filter)
+        result["calculate"] = from_str(self.calculate)
+        result["from"] = to_class(LookupData, self.transform_from)
+        result["lookup"] = from_str(self.lookup)
+        result["bin"] = from_union([from_bool, lambda x: to_class(BinParams, x)], self.bin)
+        result["field"] = from_str(self.field)
+        result["timeUnit"] = to_enum(TimeUnit, self.time_unit)
+        result["aggregate"] = from_list(lambda x: to_class(AggregatedFieldDef, x), self.aggregate)
         if self.transform_as is not None:
             result["as"] = from_union([lambda x: from_list(from_str, x), from_str, from_none], self.transform_as)
-        if self.calculate is not None:
-            result["calculate"] = from_union([from_str, from_none], self.calculate)
         if self.default is not None:
             result["default"] = from_union([from_str, from_none], self.default)
-        if self.transform_from is not None:
-            result["from"] = from_union([lambda x: to_class(LookupData, x), from_none], self.transform_from)
-        if self.lookup is not None:
-            result["lookup"] = from_union([from_str, from_none], self.lookup)
-        if self.bin is not None:
-            result["bin"] = from_union([from_bool, lambda x: to_class(BinParams, x), from_none], self.bin)
-        if self.field is not None:
-            result["field"] = from_union([from_str, from_none], self.field)
-        if self.time_unit is not None:
-            result["timeUnit"] = from_union([lambda x: to_enum(TimeUnit, x), from_none], self.time_unit)
-        if self.aggregate is not None:
-            result["aggregate"] = from_union([lambda x: from_list(lambda x: to_class(AggregatedFieldDef, x), x), from_none], self.aggregate)
         if self.groupby is not None:
             result["groupby"] = from_union([lambda x: from_list(from_str, x), from_none], self.groupby)
         return result
@@ -7453,6 +7410,21 @@ class Transform:
 class LayerSpec:
     """Unit spec that can have a composite mark."""
 
+    layer: list['LayerSpec']
+    """Layer or single view specifications to be layered.
+    
+    __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
+    layering facet specifications is not allowed.
+    """
+    encoding: Encoding
+    """A key-value mapping between encoding channels and definition of fields."""
+
+    mark: MarkDef | Mark
+    """A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
+    `"line"`,
+    * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
+    object](mark.html#mark-def).
+    """
     data: Data | None = None
     """An object describing the data source"""
 
@@ -7478,12 +7450,6 @@ class LayerSpec:
     
     __See also:__ The documentation for [width and height](size.html) contains more examples.
     """
-    layer: 'list[LayerSpec] | None' = None
-    """Layer or single view specifications to be layered.
-    
-    __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
-    layering facet specifications is not allowed.
-    """
     name: str | None = None
     """Name of the visualization for later reference."""
 
@@ -7518,15 +7484,6 @@ class LayerSpec:
     
     __See also:__ The documentation for [width and height](size.html) contains more examples.
     """
-    encoding: Encoding | None = None
-    """A key-value mapping between encoding channels and definition of fields."""
-
-    mark: MarkDef | Mark | None = None
-    """A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
-    `"line"`,
-    * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
-    object](mark.html#mark-def).
-    """
     projection: Projection | None = None
     """An object defining properties of geographic projection.
     
@@ -7539,31 +7496,32 @@ class LayerSpec:
     @staticmethod
     def from_dict(obj: Any) -> 'LayerSpec':
         assert isinstance(obj, dict)
+        layer = from_list(LayerSpec.from_dict, obj.get("layer"))
+        encoding = Encoding.from_dict(obj.get("encoding"))
+        mark = from_union([MarkDef.from_dict, Mark], obj.get("mark"))
         data = from_union([Data.from_dict, from_none], obj.get("data"))
         description = from_union([from_str, from_none], obj.get("description"))
         height = from_union([from_float, from_none], obj.get("height"))
-        layer = from_union([lambda x: from_list(LayerSpec.from_dict, x), from_none], obj.get("layer"))
         name = from_union([from_str, from_none], obj.get("name"))
         resolve = from_union([Resolve.from_dict, from_none], obj.get("resolve"))
         title = from_union([TitleParams.from_dict, from_str, from_none], obj.get("title"))
         transform = from_union([lambda x: from_list(Transform.from_dict, x), from_none], obj.get("transform"))
         width = from_union([from_float, from_none], obj.get("width"))
-        encoding = from_union([Encoding.from_dict, from_none], obj.get("encoding"))
-        mark = from_union([MarkDef.from_dict, Mark, from_none], obj.get("mark"))
         projection = from_union([Projection.from_dict, from_none], obj.get("projection"))
         selection = from_union([lambda x: from_dict(SelectionDef.from_dict, x), from_none], obj.get("selection"))
-        return LayerSpec(data, description, height, layer, name, resolve, title, transform, width, encoding, mark, projection, selection)
+        return LayerSpec(layer, encoding, mark, data, description, height, name, resolve, title, transform, width, projection, selection)
 
     def to_dict(self) -> dict:
         result: dict = {}
+        result["layer"] = from_list(lambda x: to_class(LayerSpec, x), self.layer)
+        result["encoding"] = to_class(Encoding, self.encoding)
+        result["mark"] = from_union([lambda x: to_class(MarkDef, x), lambda x: to_enum(Mark, x)], self.mark)
         if self.data is not None:
             result["data"] = from_union([lambda x: to_class(Data, x), from_none], self.data)
         if self.description is not None:
             result["description"] = from_union([from_str, from_none], self.description)
         if self.height is not None:
             result["height"] = from_union([to_float, from_none], self.height)
-        if self.layer is not None:
-            result["layer"] = from_union([lambda x: from_list(lambda x: to_class(LayerSpec, x), x), from_none], self.layer)
         if self.name is not None:
             result["name"] = from_union([from_str, from_none], self.name)
         if self.resolve is not None:
@@ -7574,10 +7532,6 @@ class LayerSpec:
             result["transform"] = from_union([lambda x: from_list(lambda x: to_class(Transform, x), x), from_none], self.transform)
         if self.width is not None:
             result["width"] = from_union([to_float, from_none], self.width)
-        if self.encoding is not None:
-            result["encoding"] = from_union([lambda x: to_class(Encoding, x), from_none], self.encoding)
-        if self.mark is not None:
-            result["mark"] = from_union([lambda x: to_class(MarkDef, x), lambda x: to_enum(Mark, x), from_none], self.mark)
         if self.projection is not None:
             result["projection"] = from_union([lambda x: to_class(Projection, x), from_none], self.projection)
         if self.selection is not None:
@@ -7616,6 +7570,38 @@ class Repeat:
 class Spec:
     """Unit spec that can have a composite mark."""
 
+    layer: list[LayerSpec]
+    """Layer or single view specifications to be layered.
+    
+    __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
+    layering facet specifications is not allowed.
+    """
+    encoding: Encoding
+    """A key-value mapping between encoding channels and definition of fields."""
+
+    mark: MarkDef | Mark
+    """A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
+    `"line"`,
+    * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
+    object](mark.html#mark-def).
+    """
+    facet: FacetMapping
+    """An object that describes mappings between `row` and `column` channels and their field
+    definitions.
+    """
+    spec: 'Spec'
+    """A specification of the view that gets faceted."""
+
+    repeat: Repeat
+    """An object that describes what fields should be repeated into views that are laid out as a
+    `row` or `column`.
+    """
+    vconcat: list['Spec']
+    """A list of views that should be concatenated and put into a column."""
+
+    hconcat: list['Spec']
+    """A list of views that should be concatenated and put into a row."""
+
     data: Data | None = None
     """An object describing the data source"""
 
@@ -7641,12 +7627,6 @@ class Spec:
     
     __See also:__ The documentation for [width and height](size.html) contains more examples.
     """
-    layer: list[LayerSpec] | None = None
-    """Layer or single view specifications to be layered.
-    
-    __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
-    layering facet specifications is not allowed.
-    """
     name: str | None = None
     """Name of the visualization for later reference."""
 
@@ -7689,15 +7669,6 @@ class Spec:
     
     __See also:__ The documentation for [width and height](size.html) contains more examples.
     """
-    encoding: Encoding | None = None
-    """A key-value mapping between encoding channels and definition of fields."""
-
-    mark: MarkDef | Mark | None = None
-    """A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
-    `"line"`,
-    * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
-    object](mark.html#mark-def).
-    """
     projection: Projection | None = None
     """An object defining properties of geographic projection.
     
@@ -7707,56 +7678,45 @@ class Spec:
     selection: dict[str, SelectionDef] | None = None
     """A key-value mapping between selection names and definitions."""
 
-    facet: FacetMapping | None = None
-    """An object that describes mappings between `row` and `column` channels and their field
-    definitions.
-    """
-    spec: 'Spec | None' = None
-    """A specification of the view that gets faceted."""
-
-    repeat: Repeat | None = None
-    """An object that describes what fields should be repeated into views that are laid out as a
-    `row` or `column`.
-    """
-    vconcat: 'list[Spec] | None' = None
-    """A list of views that should be concatenated and put into a column."""
-
-    hconcat: 'list[Spec] | None' = None
-    """A list of views that should be concatenated and put into a row."""
-
     @staticmethod
     def from_dict(obj: Any) -> 'Spec':
         assert isinstance(obj, dict)
+        layer = from_list(LayerSpec.from_dict, obj.get("layer"))
+        encoding = Encoding.from_dict(obj.get("encoding"))
+        mark = from_union([MarkDef.from_dict, Mark], obj.get("mark"))
+        facet = FacetMapping.from_dict(obj.get("facet"))
+        spec = Spec.from_dict(obj.get("spec"))
+        repeat = Repeat.from_dict(obj.get("repeat"))
+        vconcat = from_list(Spec.from_dict, obj.get("vconcat"))
+        hconcat = from_list(Spec.from_dict, obj.get("hconcat"))
         data = from_union([Data.from_dict, from_none], obj.get("data"))
         description = from_union([from_str, from_none], obj.get("description"))
         height = from_union([from_float, from_none], obj.get("height"))
-        layer = from_union([lambda x: from_list(LayerSpec.from_dict, x), from_none], obj.get("layer"))
         name = from_union([from_str, from_none], obj.get("name"))
         resolve = from_union([Resolve.from_dict, from_none], obj.get("resolve"))
         title = from_union([TitleParams.from_dict, from_str, from_none], obj.get("title"))
         transform = from_union([lambda x: from_list(Transform.from_dict, x), from_none], obj.get("transform"))
         width = from_union([from_float, from_none], obj.get("width"))
-        encoding = from_union([Encoding.from_dict, from_none], obj.get("encoding"))
-        mark = from_union([MarkDef.from_dict, Mark, from_none], obj.get("mark"))
         projection = from_union([Projection.from_dict, from_none], obj.get("projection"))
         selection = from_union([lambda x: from_dict(SelectionDef.from_dict, x), from_none], obj.get("selection"))
-        facet = from_union([FacetMapping.from_dict, from_none], obj.get("facet"))
-        spec = from_union([Spec.from_dict, from_none], obj.get("spec"))
-        repeat = from_union([Repeat.from_dict, from_none], obj.get("repeat"))
-        vconcat = from_union([lambda x: from_list(Spec.from_dict, x), from_none], obj.get("vconcat"))
-        hconcat = from_union([lambda x: from_list(Spec.from_dict, x), from_none], obj.get("hconcat"))
-        return Spec(data, description, height, layer, name, resolve, title, transform, width, encoding, mark, projection, selection, facet, spec, repeat, vconcat, hconcat)
+        return Spec(layer, encoding, mark, facet, spec, repeat, vconcat, hconcat, data, description, height, name, resolve, title, transform, width, projection, selection)
 
     def to_dict(self) -> dict:
         result: dict = {}
+        result["layer"] = from_list(lambda x: to_class(LayerSpec, x), self.layer)
+        result["encoding"] = to_class(Encoding, self.encoding)
+        result["mark"] = from_union([lambda x: to_class(MarkDef, x), lambda x: to_enum(Mark, x)], self.mark)
+        result["facet"] = to_class(FacetMapping, self.facet)
+        result["spec"] = to_class(Spec, self.spec)
+        result["repeat"] = to_class(Repeat, self.repeat)
+        result["vconcat"] = from_list(lambda x: to_class(Spec, x), self.vconcat)
+        result["hconcat"] = from_list(lambda x: to_class(Spec, x), self.hconcat)
         if self.data is not None:
             result["data"] = from_union([lambda x: to_class(Data, x), from_none], self.data)
         if self.description is not None:
             result["description"] = from_union([from_str, from_none], self.description)
         if self.height is not None:
             result["height"] = from_union([to_float, from_none], self.height)
-        if self.layer is not None:
-            result["layer"] = from_union([lambda x: from_list(lambda x: to_class(LayerSpec, x), x), from_none], self.layer)
         if self.name is not None:
             result["name"] = from_union([from_str, from_none], self.name)
         if self.resolve is not None:
@@ -7767,29 +7727,47 @@ class Spec:
             result["transform"] = from_union([lambda x: from_list(lambda x: to_class(Transform, x), x), from_none], self.transform)
         if self.width is not None:
             result["width"] = from_union([to_float, from_none], self.width)
-        if self.encoding is not None:
-            result["encoding"] = from_union([lambda x: to_class(Encoding, x), from_none], self.encoding)
-        if self.mark is not None:
-            result["mark"] = from_union([lambda x: to_class(MarkDef, x), lambda x: to_enum(Mark, x), from_none], self.mark)
         if self.projection is not None:
             result["projection"] = from_union([lambda x: to_class(Projection, x), from_none], self.projection)
         if self.selection is not None:
             result["selection"] = from_union([lambda x: from_dict(lambda x: to_class(SelectionDef, x), x), from_none], self.selection)
-        if self.facet is not None:
-            result["facet"] = from_union([lambda x: to_class(FacetMapping, x), from_none], self.facet)
-        if self.spec is not None:
-            result["spec"] = from_union([lambda x: to_class(Spec, x), from_none], self.spec)
-        if self.repeat is not None:
-            result["repeat"] = from_union([lambda x: to_class(Repeat, x), from_none], self.repeat)
-        if self.vconcat is not None:
-            result["vconcat"] = from_union([lambda x: from_list(lambda x: to_class(Spec, x), x), from_none], self.vconcat)
-        if self.hconcat is not None:
-            result["hconcat"] = from_union([lambda x: from_list(lambda x: to_class(Spec, x), x), from_none], self.hconcat)
         return result
 
 
 @dataclass
 class TopLevel:
+    encoding: EncodingWithFacet
+    """A key-value mapping between encoding channels and definition of fields."""
+
+    mark: MarkDef | Mark
+    """A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
+    `"line"`,
+    * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
+    object](mark.html#mark-def).
+    """
+    layer: list[LayerSpec]
+    """Layer or single view specifications to be layered.
+    
+    __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
+    layering facet specifications is not allowed.
+    """
+    facet: FacetMapping
+    """An object that describes mappings between `row` and `column` channels and their field
+    definitions.
+    """
+    spec: Spec
+    """A specification of the view that gets faceted."""
+
+    repeat: Repeat
+    """An object that describes what fields should be repeated into views that are laid out as a
+    `row` or `column`.
+    """
+    vconcat: list[Spec]
+    """A list of views that should be concatenated and put into a column."""
+
+    hconcat: list[Spec]
+    """A list of views that should be concatenated and put into a row."""
+
     schema: str | None = None
     """URL to [JSON schema](http://json-schema.org/) for a Vega-Lite specification. Unless you
     have a reason to change this, use `https://vega.github.io/schema/vega-lite/v2.json`.
@@ -7820,9 +7798,6 @@ class TopLevel:
     description: str | None = None
     """Description of this mark for commenting purpose."""
 
-    encoding: EncodingWithFacet | None = None
-    """A key-value mapping between encoding channels and definition of fields."""
-
     height: float | None = None
     """The height of a visualization.
     
@@ -7842,12 +7817,6 @@ class TopLevel:
     
     __See also:__ The documentation for [width and height](size.html) contains more examples.
     """
-    mark: MarkDef | Mark | None = None
-    """A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
-    `"line"`,
-    * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
-    object](mark.html#mark-def).
-    """
     name: str | None = None
     """Name of the visualization for later reference."""
 
@@ -7896,12 +7865,6 @@ class TopLevel:
     
     __See also:__ The documentation for [width and height](size.html) contains more examples.
     """
-    layer: list[LayerSpec] | None = None
-    """Layer or single view specifications to be layered.
-    
-    __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
-    layering facet specifications is not allowed.
-    """
     resolve: Resolve | None = None
     """Scale, axis, and legend resolutions for layers.
     
@@ -7913,35 +7876,25 @@ class TopLevel:
     
     Scale, axis, and legend resolutions for horizontally concatenated charts.
     """
-    facet: FacetMapping | None = None
-    """An object that describes mappings between `row` and `column` channels and their field
-    definitions.
-    """
-    spec: Spec | None = None
-    """A specification of the view that gets faceted."""
-
-    repeat: Repeat | None = None
-    """An object that describes what fields should be repeated into views that are laid out as a
-    `row` or `column`.
-    """
-    vconcat: list[Spec] | None = None
-    """A list of views that should be concatenated and put into a column."""
-
-    hconcat: list[Spec] | None = None
-    """A list of views that should be concatenated and put into a row."""
 
     @staticmethod
     def from_dict(obj: Any) -> 'TopLevel':
         assert isinstance(obj, dict)
+        encoding = EncodingWithFacet.from_dict(obj.get("encoding"))
+        mark = from_union([MarkDef.from_dict, Mark], obj.get("mark"))
+        layer = from_list(LayerSpec.from_dict, obj.get("layer"))
+        facet = FacetMapping.from_dict(obj.get("facet"))
+        spec = Spec.from_dict(obj.get("spec"))
+        repeat = Repeat.from_dict(obj.get("repeat"))
+        vconcat = from_list(Spec.from_dict, obj.get("vconcat"))
+        hconcat = from_list(Spec.from_dict, obj.get("hconcat"))
         schema = from_union([from_str, from_none], obj.get("$schema"))
         autosize = from_union([AutoSizeParams.from_dict, AutosizeType, from_none], obj.get("autosize"))
         background = from_union([from_str, from_none], obj.get("background"))
         config = from_union([Config.from_dict, from_none], obj.get("config"))
         data = from_union([Data.from_dict, from_none], obj.get("data"))
         description = from_union([from_str, from_none], obj.get("description"))
-        encoding = from_union([EncodingWithFacet.from_dict, from_none], obj.get("encoding"))
         height = from_union([from_float, from_none], obj.get("height"))
-        mark = from_union([MarkDef.from_dict, Mark, from_none], obj.get("mark"))
         name = from_union([from_str, from_none], obj.get("name"))
         padding = from_union([from_float, PaddingClass.from_dict, from_none], obj.get("padding"))
         projection = from_union([Projection.from_dict, from_none], obj.get("projection"))
@@ -7949,17 +7902,19 @@ class TopLevel:
         title = from_union([TitleParams.from_dict, from_str, from_none], obj.get("title"))
         transform = from_union([lambda x: from_list(Transform.from_dict, x), from_none], obj.get("transform"))
         width = from_union([from_float, from_none], obj.get("width"))
-        layer = from_union([lambda x: from_list(LayerSpec.from_dict, x), from_none], obj.get("layer"))
         resolve = from_union([Resolve.from_dict, from_none], obj.get("resolve"))
-        facet = from_union([FacetMapping.from_dict, from_none], obj.get("facet"))
-        spec = from_union([Spec.from_dict, from_none], obj.get("spec"))
-        repeat = from_union([Repeat.from_dict, from_none], obj.get("repeat"))
-        vconcat = from_union([lambda x: from_list(Spec.from_dict, x), from_none], obj.get("vconcat"))
-        hconcat = from_union([lambda x: from_list(Spec.from_dict, x), from_none], obj.get("hconcat"))
-        return TopLevel(schema, autosize, background, config, data, description, encoding, height, mark, name, padding, projection, selection, title, transform, width, layer, resolve, facet, spec, repeat, vconcat, hconcat)
+        return TopLevel(encoding, mark, layer, facet, spec, repeat, vconcat, hconcat, schema, autosize, background, config, data, description, height, name, padding, projection, selection, title, transform, width, resolve)
 
     def to_dict(self) -> dict:
         result: dict = {}
+        result["encoding"] = to_class(EncodingWithFacet, self.encoding)
+        result["mark"] = from_union([lambda x: to_class(MarkDef, x), lambda x: to_enum(Mark, x)], self.mark)
+        result["layer"] = from_list(lambda x: to_class(LayerSpec, x), self.layer)
+        result["facet"] = to_class(FacetMapping, self.facet)
+        result["spec"] = to_class(Spec, self.spec)
+        result["repeat"] = to_class(Repeat, self.repeat)
+        result["vconcat"] = from_list(lambda x: to_class(Spec, x), self.vconcat)
+        result["hconcat"] = from_list(lambda x: to_class(Spec, x), self.hconcat)
         if self.schema is not None:
             result["$schema"] = from_union([from_str, from_none], self.schema)
         if self.autosize is not None:
@@ -7972,12 +7927,8 @@ class TopLevel:
             result["data"] = from_union([lambda x: to_class(Data, x), from_none], self.data)
         if self.description is not None:
             result["description"] = from_union([from_str, from_none], self.description)
-        if self.encoding is not None:
-            result["encoding"] = from_union([lambda x: to_class(EncodingWithFacet, x), from_none], self.encoding)
         if self.height is not None:
             result["height"] = from_union([to_float, from_none], self.height)
-        if self.mark is not None:
-            result["mark"] = from_union([lambda x: to_class(MarkDef, x), lambda x: to_enum(Mark, x), from_none], self.mark)
         if self.name is not None:
             result["name"] = from_union([from_str, from_none], self.name)
         if self.padding is not None:
@@ -7992,20 +7943,8 @@ class TopLevel:
             result["transform"] = from_union([lambda x: from_list(lambda x: to_class(Transform, x), x), from_none], self.transform)
         if self.width is not None:
             result["width"] = from_union([to_float, from_none], self.width)
-        if self.layer is not None:
-            result["layer"] = from_union([lambda x: from_list(lambda x: to_class(LayerSpec, x), x), from_none], self.layer)
         if self.resolve is not None:
             result["resolve"] = from_union([lambda x: to_class(Resolve, x), from_none], self.resolve)
-        if self.facet is not None:
-            result["facet"] = from_union([lambda x: to_class(FacetMapping, x), from_none], self.facet)
-        if self.spec is not None:
-            result["spec"] = from_union([lambda x: to_class(Spec, x), from_none], self.spec)
-        if self.repeat is not None:
-            result["repeat"] = from_union([lambda x: to_class(Repeat, x), from_none], self.repeat)
-        if self.vconcat is not None:
-            result["vconcat"] = from_union([lambda x: from_list(lambda x: to_class(Spec, x), x), from_none], self.vconcat)
-        if self.hconcat is not None:
-            result["hconcat"] = from_union([lambda x: from_list(lambda x: to_class(Spec, x), x), from_none], self.hconcat)
         return result
 
 
diff --git a/head/schema-ruby/test/inputs/schema/required-in-any-of.schema/default/TopLevel.rb b/head/schema-ruby/test/inputs/schema/required-in-any-of.schema/default/TopLevel.rb
new file mode 100644
index 0000000..bcec404
--- /dev/null
+++ b/head/schema-ruby/test/inputs/schema/required-in-any-of.schema/default/TopLevel.rb
@@ -0,0 +1,73 @@
+# This code may look unusually verbose for Ruby (and it is), but
+# it performs some subtle and complex validation of JSON data.
+#
+# To parse this JSON, add 'dry-struct' and 'dry-types' gems, then do:
+#
+#   top_level = TopLevel.from_json! "{…}"
+#   puts top_level.anyof.anyof_name
+#
+# If from_json! succeeds, the value returned matches the schema.
+
+require 'json'
+require 'dry-types'
+require 'dry-struct'
+
+module Types
+  include Dry.Types(default: :nominal)
+
+  Hash   = Strict::Hash
+  String = Strict::String
+end
+
+class Anyof < Dry::Struct
+  attribute :anyof_name, Types::String
+  attribute :size,       Types::String.optional
+
+  def self.from_dynamic!(d)
+    d = Types::Hash[d]
+    new(
+      anyof_name: d.fetch("name"),
+      size:       d["size"],
+    )
+  end
+
+  def self.from_json!(json)
+    from_dynamic!(JSON.parse(json))
+  end
+
+  def to_dynamic
+    {
+      "name" => anyof_name,
+      "size" => size,
+    }
+  end
+
+  def to_json(options = nil)
+    JSON.generate(to_dynamic, options)
+  end
+end
+
+class TopLevel < Dry::Struct
+  attribute :anyof, Anyof
+
+  def self.from_dynamic!(d)
+    d = Types::Hash[d]
+    new(
+      anyof: Anyof.from_dynamic!(d.fetch("anyof")),
+    )
+  end
+
+  def self.from_json!(json)
+    from_dynamic!(JSON.parse(json))
+  end
+
+  def to_dynamic
+    {
+      "anyof" => anyof.to_dynamic,
+    }
+  end
+
+  def to_json(options = nil)
+    JSON.generate(to_dynamic, options)
+  end
+end
diff --git a/base/schema-ruby/test/inputs/schema/vega-lite.schema/default/TopLevel.rb b/head/schema-ruby/test/inputs/schema/vega-lite.schema/default/TopLevel.rb
index 04321e6..d316325 100644
--- a/base/schema-ruby/test/inputs/schema/vega-lite.schema/default/TopLevel.rb
+++ b/head/schema-ruby/test/inputs/schema/vega-lite.schema/default/TopLevel.rb
@@ -4,7 +4,7 @@
 # To parse this JSON, add 'dry-struct' and 'dry-types' gems, then do:
 #
 #   top_level = TopLevel.from_json! "{…}"
-#   puts top_level.hconcat&.first.hconcat&.first.hconcat&.first
+#   puts top_level.hconcat.first.hconcat.first.hconcat.first
 #
 # If from_json! succeeds, the value returned matches the schema.
 
@@ -1962,7 +1962,7 @@ end
 class VGScheme < Dry::Struct
   attribute :count,  Types::Double.optional
   attribute :extent, Types.Array(Types::Double).optional
-  attribute :scheme, Types::String.optional
+  attribute :scheme, Types::String
   attribute :step,   Types::Double.optional
 
   def self.from_dynamic!(d)
@@ -1970,7 +1970,7 @@ class VGScheme < Dry::Struct
     new(
       count:  d["count"],
       extent: d["extent"],
-      scheme: d["scheme"],
+      scheme: d.fetch("scheme"),
       step:   d["step"],
     )
   end
@@ -2543,7 +2543,7 @@ end
 class VGBinding < Dry::Struct
   attribute :element,            Types::String.optional
   attribute :input,              Types::String
-  attribute :vg_binding_options, Types.Array(Types::String).optional
+  attribute :vg_binding_options, Types.Array(Types::String)
   attribute :max,                Types::Double.optional
   attribute :min,                Types::Double.optional
   attribute :step,               Types::Double.optional
@@ -2553,7 +2553,7 @@ class VGBinding < Dry::Struct
     new(
       element:            d["element"],
       input:              d.fetch("input"),
-      vg_binding_options: d["options"],
+      vg_binding_options: d.fetch("options"),
       max:                d["max"],
       min:                d["min"],
       step:               d["step"],
@@ -4134,24 +4134,24 @@ class DataClass < Dry::Struct
 
   # An URL from which to load the data set. Use the `format.type` property
   # to ensure the loaded data is correctly parsed.
-  attribute :url, Types::String.optional
+  attribute :url, Types::String
 
   # The full data set, included inline. This can be an array of objects or primitive values
   # or a string.
   # Arrays of primitive values are ingested as objects with a `data` property. Strings are
   # parsed according to the specified format type.
-  attribute :values, Types.Instance(Values).optional
+  attribute :values, Types.Instance(Values)
 
   # Provide a placeholder name and bind data at runtime.
-  attribute :data_name, Types::String.optional
+  attribute :data_name, Types::String
 
   def self.from_dynamic!(d)
     d = Types::Hash[d]
     new(
       data_format: d["format"] ? DataFormat.from_dynamic!(d["format"]) : nil,
-      url:         d["url"],
-      values:      d["values"] ? Values.from_dynamic!(d["values"]) : nil,
-      data_name:   d["name"],
+      url:         d.fetch("url"),
+      values:      Values.from_dynamic!(d.fetch("values")),
+      data_name:   d.fetch("name"),
     )
   end
 
@@ -4163,7 +4163,7 @@ class DataClass < Dry::Struct
     {
       "format" => data_format&.to_dynamic,
       "url"    => url,
-      "values" => values&.to_dynamic,
+      "values" => values.to_dynamic,
       "name"   => data_name,
     }
   end
@@ -4608,16 +4608,16 @@ class SelectionOperand < Dry::Struct
 end
 
 class Selection < Dry::Struct
-  attribute :selection_not, Types.Instance(SelectionOperand).optional
-  attribute :selection_and, Types.Array(Types.Instance(SelectionOperand)).optional
-  attribute :selection_or,  Types.Array(Types.Instance(SelectionOperand)).optional
+  attribute :selection_not, Types.Instance(SelectionOperand)
+  attribute :selection_and, Types.Array(Types.Instance(SelectionOperand))
+  attribute :selection_or,  Types.Array(Types.Instance(SelectionOperand))
 
   def self.from_dynamic!(d)
     d = Types::Hash[d]
     new(
-      selection_not: d["not"] ? SelectionOperand.from_dynamic!(d["not"]) : nil,
-      selection_and: d["and"]&.map { |x| SelectionOperand.from_dynamic!(x) },
-      selection_or:  d["or"]&.map { |x| SelectionOperand.from_dynamic!(x) },
+      selection_not: SelectionOperand.from_dynamic!(d.fetch("not")),
+      selection_and: d.fetch("and").map { |x| SelectionOperand.from_dynamic!(x) },
+      selection_or:  d.fetch("or").map { |x| SelectionOperand.from_dynamic!(x) },
     )
   end
 
@@ -4627,9 +4627,9 @@ class Selection < Dry::Struct
 
   def to_dynamic
     {
-      "not" => selection_not&.to_dynamic,
-      "and" => selection_and&.map { |x| x.to_dynamic },
-      "or"  => selection_or&.map { |x| x.to_dynamic },
+      "not" => selection_not.to_dynamic,
+      "and" => selection_and.map { |x| x.to_dynamic },
+      "or"  => selection_or.map { |x| x.to_dynamic },
     }
   end
 
@@ -4739,17 +4739,17 @@ class LogicalOperandPredicate < Dry::Struct
 end
 
 class Predicate < Dry::Struct
-  attribute :predicate_not, Types.Instance(LogicalOperandPredicate).optional
-  attribute :predicate_and, Types.Array(Types.Instance(LogicalOperandPredicate)).optional
-  attribute :predicate_or,  Types.Array(Types.Instance(LogicalOperandPredicate)).optional
+  attribute :predicate_not, Types.Instance(LogicalOperandPredicate)
+  attribute :predicate_and, Types.Array(Types.Instance(LogicalOperandPredicate))
+  attribute :predicate_or,  Types.Array(Types.Instance(LogicalOperandPredicate))
 
   # The value that the field should be equal to.
-  attribute :equal, Types.Instance(Equal).optional
+  attribute :equal, Types.Instance(Equal)
 
   # Field to be filtered.
   #
   # Field to be filtered
-  attribute :field, Types::String.optional
+  attribute :field, Types::String
 
   # Time unit for the field to be filtered.
   #
@@ -4758,27 +4758,27 @@ class Predicate < Dry::Struct
 
   # An array of inclusive minimum and maximum values
   # for a field value of a data item to be included in the filtered data.
-  attribute :range, Types.Array(Types.Instance(RangeElement)).optional
+  attribute :range, Types.Array(Types.Instance(RangeElement))
 
   # A set of values that the `field`'s value should be a member of,
   # for a data item included in the filtered data.
-  attribute :one_of, Types.Array(Types.Instance(Equal)).optional
+  attribute :one_of, Types.Array(Types.Instance(Equal))
 
   # Filter using a selection name.
-  attribute :selection, Types.Instance(SelectionOperand).optional
+  attribute :selection, Types.Instance(SelectionOperand)
 
   def self.from_dynamic!(d)
     d = Types::Hash[d]
     new(
-      predicate_not: d["not"] ? LogicalOperandPredicate.from_dynamic!(d["not"]) : nil,
-      predicate_and: d["and"]&.map { |x| LogicalOperandPredicate.from_dynamic!(x) },
-      predicate_or:  d["or"]&.map { |x| LogicalOperandPredicate.from_dynamic!(x) },
-      equal:         d["equal"] ? Equal.from_dynamic!(d["equal"]) : nil,
-      field:         d["field"],
+      predicate_not: LogicalOperandPredicate.from_dynamic!(d.fetch("not")),
+      predicate_and: d.fetch("and").map { |x| LogicalOperandPredicate.from_dynamic!(x) },
+      predicate_or:  d.fetch("or").map { |x| LogicalOperandPredicate.from_dynamic!(x) },
+      equal:         Equal.from_dynamic!(d.fetch("equal")),
+      field:         d.fetch("field"),
       time_unit:     d["timeUnit"],
-      range:         d["range"]&.map { |x| RangeElement.from_dynamic!(x) },
-      one_of:        d["oneOf"]&.map { |x| Equal.from_dynamic!(x) },
-      selection:     d["selection"] ? SelectionOperand.from_dynamic!(d["selection"]) : nil,
+      range:         d.fetch("range").map { |x| RangeElement.from_dynamic!(x) },
+      one_of:        d.fetch("oneOf").map { |x| Equal.from_dynamic!(x) },
+      selection:     SelectionOperand.from_dynamic!(d.fetch("selection")),
     )
   end
 
@@ -4788,15 +4788,15 @@ class Predicate < Dry::Struct
 
   def to_dynamic
     {
-      "not"       => predicate_not&.to_dynamic,
-      "and"       => predicate_and&.map { |x| x.to_dynamic },
-      "or"        => predicate_or&.map { |x| x.to_dynamic },
-      "equal"     => equal&.to_dynamic,
+      "not"       => predicate_not.to_dynamic,
+      "and"       => predicate_and.map { |x| x.to_dynamic },
+      "or"        => predicate_or.map { |x| x.to_dynamic },
+      "equal"     => equal.to_dynamic,
       "field"     => field,
       "timeUnit"  => time_unit,
-      "range"     => range&.map { |x| x.to_dynamic },
-      "oneOf"     => one_of&.map { |x| x.to_dynamic },
-      "selection" => selection&.to_dynamic,
+      "range"     => range.map { |x| x.to_dynamic },
+      "oneOf"     => one_of.map { |x| x.to_dynamic },
+      "selection" => selection.to_dynamic,
     }
   end
 
@@ -4847,7 +4847,7 @@ class ConditionalValueDefValue < Dry::Struct
 end
 
 class ConditionalValueDef < Dry::Struct
-  attribute :conditional_value_def_test, Types.Instance(LogicalOperandPredicate).optional
+  attribute :conditional_value_def_test, Types.Instance(LogicalOperandPredicate)
 
   # A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
   # `0` to `1` for opacity).
@@ -4855,14 +4855,14 @@ class ConditionalValueDef < Dry::Struct
 
   # A [selection name](selection.html), or a series of [composed
   # selections](selection.html#compose).
-  attribute :selection, Types.Instance(SelectionOperand).optional
+  attribute :selection, Types.Instance(SelectionOperand)
 
   def self.from_dynamic!(d)
     d = Types::Hash[d]
     new(
-      conditional_value_def_test: d["test"] ? LogicalOperandPredicate.from_dynamic!(d["test"]) : nil,
+      conditional_value_def_test: LogicalOperandPredicate.from_dynamic!(d.fetch("test")),
       value:                      ConditionalValueDefValue.from_dynamic!(d.fetch("value")),
-      selection:                  d["selection"] ? SelectionOperand.from_dynamic!(d["selection"]) : nil,
+      selection:                  SelectionOperand.from_dynamic!(d.fetch("selection")),
     )
   end
 
@@ -4872,9 +4872,9 @@ class ConditionalValueDef < Dry::Struct
 
   def to_dynamic
     {
-      "test"      => conditional_value_def_test&.to_dynamic,
+      "test"      => conditional_value_def_test.to_dynamic,
       "value"     => value.to_dynamic,
-      "selection" => selection&.to_dynamic,
+      "selection" => selection.to_dynamic,
     }
   end
 
@@ -5917,15 +5917,15 @@ class SortUnion < Dry::Struct
 end
 
 class ConditionalPredicateMarkPropFieldDefClass < Dry::Struct
-  attribute :conditional_def_test, Types.Instance(LogicalOperandPredicate).optional
+  attribute :conditional_def_test, Types.Instance(LogicalOperandPredicate)
 
   # A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
   # `0` to `1` for opacity).
-  attribute :value, Types.Instance(ConditionalValueDefValue).optional
+  attribute :value, Types.Instance(ConditionalValueDefValue)
 
   # A [selection name](selection.html), or a series of [composed
   # selections](selection.html#compose).
-  attribute :selection, Types.Instance(SelectionOperand).optional
+  attribute :selection, Types.Instance(SelectionOperand)
 
   # Aggregation function for the field
   # (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`).
@@ -5983,14 +5983,14 @@ class ConditionalPredicateMarkPropFieldDefClass < Dry::Struct
   # `"nominal"`).
   # It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
   # [geographic projection](projection.html) is applied.
-  attribute :conditional_def_type, Types::Type.optional
+  attribute :conditional_def_type, Types::Type
 
   def self.from_dynamic!(d)
     d = Types::Hash[d]
     new(
-      conditional_def_test: d["test"] ? LogicalOperandPredicate.from_dynamic!(d["test"]) : nil,
-      value:                d["value"] ? ConditionalValueDefValue.from_dynamic!(d["value"]) : nil,
-      selection:            d["selection"] ? SelectionOperand.from_dynamic!(d["selection"]) : nil,
+      conditional_def_test: LogicalOperandPredicate.from_dynamic!(d.fetch("test")),
+      value:                ConditionalValueDefValue.from_dynamic!(d.fetch("value")),
+      selection:            SelectionOperand.from_dynamic!(d.fetch("selection")),
       aggregate:            d["aggregate"],
       bin:                  d["bin"] ? Bin.from_dynamic!(d["bin"]) : nil,
       field:                d["field"] ? Field.from_dynamic!(d["field"]) : nil,
@@ -5998,7 +5998,7 @@ class ConditionalPredicateMarkPropFieldDefClass < Dry::Struct
       scale:                d["scale"] ? Scale.from_dynamic!(d["scale"]) : nil,
       sort:                 d["sort"] ? SortUnion.from_dynamic!(d["sort"]) : nil,
       time_unit:            d["timeUnit"],
-      conditional_def_type: d["type"],
+      conditional_def_type: d.fetch("type"),
     )
   end
 
@@ -6008,9 +6008,9 @@ class ConditionalPredicateMarkPropFieldDefClass < Dry::Struct
 
   def to_dynamic
     {
-      "test"      => conditional_def_test&.to_dynamic,
-      "value"     => value&.to_dynamic,
-      "selection" => selection&.to_dynamic,
+      "test"      => conditional_def_test.to_dynamic,
+      "value"     => value.to_dynamic,
+      "selection" => selection.to_dynamic,
       "aggregate" => aggregate,
       "bin"       => bin&.to_dynamic,
       "field"     => field&.to_dynamic,
@@ -6174,7 +6174,7 @@ class MarkPropDefWithCondition < Dry::Struct
   # `"nominal"`).
   # It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
   # [geographic projection](projection.html) is applied.
-  attribute :mark_prop_def_with_condition_type, Types::Type.optional
+  attribute :mark_prop_def_with_condition_type, Types::Type
 
   # A constant value in visual domain.
   attribute :value, Types.Instance(ConditionalValueDefValue).optional
@@ -6190,7 +6190,7 @@ class MarkPropDefWithCondition < Dry::Struct
       scale:                             d["scale"] ? Scale.from_dynamic!(d["scale"]) : nil,
       sort:                              d["sort"] ? SortUnion.from_dynamic!(d["sort"]) : nil,
       time_unit:                         d["timeUnit"],
-      mark_prop_def_with_condition_type: d["type"],
+      mark_prop_def_with_condition_type: d.fetch("type"),
       value:                             d["value"] ? ConditionalValueDefValue.from_dynamic!(d["value"]) : nil,
     )
   end
@@ -6473,15 +6473,15 @@ class Detail < Dry::Struct
 end
 
 class ConditionalPredicateFieldDefClass < Dry::Struct
-  attribute :conditional_def_test, Types.Instance(LogicalOperandPredicate).optional
+  attribute :conditional_def_test, Types.Instance(LogicalOperandPredicate)
 
   # A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
   # `0` to `1` for opacity).
-  attribute :value, Types.Instance(ConditionalValueDefValue).optional
+  attribute :value, Types.Instance(ConditionalValueDefValue)
 
   # A [selection name](selection.html), or a series of [composed
   # selections](selection.html#compose).
-  attribute :selection, Types.Instance(SelectionOperand).optional
+  attribute :selection, Types.Instance(SelectionOperand)
 
   # Aggregation function for the field
   # (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`).
@@ -6518,19 +6518,19 @@ class ConditionalPredicateFieldDefClass < Dry::Struct
   # `"nominal"`).
   # It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
   # [geographic projection](projection.html) is applied.
-  attribute :conditional_def_type, Types::Type.optional
+  attribute :conditional_def_type, Types::Type
 
   def self.from_dynamic!(d)
     d = Types::Hash[d]
     new(
-      conditional_def_test: d["test"] ? LogicalOperandPredicate.from_dynamic!(d["test"]) : nil,
-      value:                d["value"] ? ConditionalValueDefValue.from_dynamic!(d["value"]) : nil,
-      selection:            d["selection"] ? SelectionOperand.from_dynamic!(d["selection"]) : nil,
+      conditional_def_test: LogicalOperandPredicate.from_dynamic!(d.fetch("test")),
+      value:                ConditionalValueDefValue.from_dynamic!(d.fetch("value")),
+      selection:            SelectionOperand.from_dynamic!(d.fetch("selection")),
       aggregate:            d["aggregate"],
       bin:                  d["bin"] ? Bin.from_dynamic!(d["bin"]) : nil,
       field:                d["field"] ? Field.from_dynamic!(d["field"]) : nil,
       time_unit:            d["timeUnit"],
-      conditional_def_type: d["type"],
+      conditional_def_type: d.fetch("type"),
     )
   end
 
@@ -6540,9 +6540,9 @@ class ConditionalPredicateFieldDefClass < Dry::Struct
 
   def to_dynamic
     {
-      "test"      => conditional_def_test&.to_dynamic,
-      "value"     => value&.to_dynamic,
-      "selection" => selection&.to_dynamic,
+      "test"      => conditional_def_test.to_dynamic,
+      "value"     => value.to_dynamic,
+      "selection" => selection.to_dynamic,
       "aggregate" => aggregate,
       "bin"       => bin&.to_dynamic,
       "field"     => field&.to_dynamic,
@@ -6655,7 +6655,7 @@ class DefWithCondition < Dry::Struct
   # `"nominal"`).
   # It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
   # [geographic projection](projection.html) is applied.
-  attribute :def_with_condition_type, Types::Type.optional
+  attribute :def_with_condition_type, Types::Type
 
   # A constant value in visual domain.
   attribute :value, Types.Instance(ConditionalValueDefValue).optional
@@ -6668,7 +6668,7 @@ class DefWithCondition < Dry::Struct
       condition:               d["condition"] ? HrefCondition.from_dynamic!(d["condition"]) : nil,
       field:                   d["field"] ? Field.from_dynamic!(d["field"]) : nil,
       time_unit:               d["timeUnit"],
-      def_with_condition_type: d["type"],
+      def_with_condition_type: d.fetch("type"),
       value:                   d["value"] ? ConditionalValueDefValue.from_dynamic!(d["value"]) : nil,
     )
   end
@@ -6808,15 +6808,15 @@ class Order < Dry::Struct
 end
 
 class ConditionalPredicateTextFieldDefClass < Dry::Struct
-  attribute :conditional_def_test, Types.Instance(LogicalOperandPredicate).optional
+  attribute :conditional_def_test, Types.Instance(LogicalOperandPredicate)
 
   # A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
   # `0` to `1` for opacity).
-  attribute :value, Types.Instance(ConditionalValueDefValue).optional
+  attribute :value, Types.Instance(ConditionalValueDefValue)
 
   # A [selection name](selection.html), or a series of [composed
   # selections](selection.html#compose).
-  attribute :selection, Types.Instance(SelectionOperand).optional
+  attribute :selection, Types.Instance(SelectionOperand)
 
   # Aggregation function for the field
   # (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`).
@@ -6857,20 +6857,20 @@ class ConditionalPredicateTextFieldDefClass < Dry::Struct
   # `"nominal"`).
   # It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
   # [geographic projection](projection.html) is applied.
-  attribute :conditional_def_type, Types::Type.optional
+  attribute :conditional_def_type, Types::Type
 
   def self.from_dynamic!(d)
     d = Types::Hash[d]
     new(
-      conditional_def_test:   d["test"] ? LogicalOperandPredicate.from_dynamic!(d["test"]) : nil,
-      value:                  d["value"] ? ConditionalValueDefValue.from_dynamic!(d["value"]) : nil,
-      selection:              d["selection"] ? SelectionOperand.from_dynamic!(d["selection"]) : nil,
+      conditional_def_test:   LogicalOperandPredicate.from_dynamic!(d.fetch("test")),
+      value:                  ConditionalValueDefValue.from_dynamic!(d.fetch("value")),
+      selection:              SelectionOperand.from_dynamic!(d.fetch("selection")),
       aggregate:              d["aggregate"],
       bin:                    d["bin"] ? Bin.from_dynamic!(d["bin"]) : nil,
       field:                  d["field"] ? Field.from_dynamic!(d["field"]) : nil,
       conditional_def_format: d["format"],
       time_unit:              d["timeUnit"],
-      conditional_def_type:   d["type"],
+      conditional_def_type:   d.fetch("type"),
     )
   end
 
@@ -6880,9 +6880,9 @@ class ConditionalPredicateTextFieldDefClass < Dry::Struct
 
   def to_dynamic
     {
-      "test"      => conditional_def_test&.to_dynamic,
-      "value"     => value&.to_dynamic,
-      "selection" => selection&.to_dynamic,
+      "test"      => conditional_def_test.to_dynamic,
+      "value"     => value.to_dynamic,
+      "selection" => selection.to_dynamic,
       "aggregate" => aggregate,
       "bin"       => bin&.to_dynamic,
       "field"     => field&.to_dynamic,
@@ -7002,7 +7002,7 @@ class TextDefWithCondition < Dry::Struct
   # `"nominal"`).
   # It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
   # [geographic projection](projection.html) is applied.
-  attribute :text_def_with_condition_type, Types::Type.optional
+  attribute :text_def_with_condition_type, Types::Type
 
   # A constant value in visual domain.
   attribute :value, Types.Instance(ConditionalValueDefValue).optional
@@ -7016,7 +7016,7 @@ class TextDefWithCondition < Dry::Struct
       field:                          d["field"] ? Field.from_dynamic!(d["field"]) : nil,
       text_def_with_condition_format: d["format"],
       time_unit:                      d["timeUnit"],
-      text_def_with_condition_type:   d["type"],
+      text_def_with_condition_type:   d.fetch("type"),
       value:                          d["value"] ? ConditionalValueDefValue.from_dynamic!(d["value"]) : nil,
     )
   end
@@ -7371,11 +7371,11 @@ class XClass < Dry::Struct
   # `"nominal"`).
   # It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
   # [geographic projection](projection.html) is applied.
-  attribute :def_type, Types::Type.optional
+  attribute :def_type, Types::Type
 
   # A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
   # `0` to `1` for opacity).
-  attribute :value, Types.Instance(ConditionalValueDefValue).optional
+  attribute :value, Types.Instance(ConditionalValueDefValue)
 
   def self.from_dynamic!(d)
     d = Types::Hash[d]
@@ -7388,8 +7388,8 @@ class XClass < Dry::Struct
       sort:      d["sort"] ? SortUnion.from_dynamic!(d["sort"]) : nil,
       stack:     d["stack"],
       time_unit: d["timeUnit"],
-      def_type:  d["type"],
-      value:     d["value"] ? ConditionalValueDefValue.from_dynamic!(d["value"]) : nil,
+      def_type:  d.fetch("type"),
+      value:     ConditionalValueDefValue.from_dynamic!(d.fetch("value")),
     )
   end
 
@@ -7408,7 +7408,7 @@ class XClass < Dry::Struct
       "stack"     => stack,
       "timeUnit"  => time_unit,
       "type"      => def_type,
-      "value"     => value&.to_dynamic,
+      "value"     => value.to_dynamic,
     }
   end
 
@@ -7461,11 +7461,11 @@ class X2Class < Dry::Struct
   # `"nominal"`).
   # It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
   # [geographic projection](projection.html) is applied.
-  attribute :def_type, Types::Type.optional
+  attribute :def_type, Types::Type
 
   # A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
   # `0` to `1` for opacity).
-  attribute :value, Types.Instance(ConditionalValueDefValue).optional
+  attribute :value, Types.Instance(ConditionalValueDefValue)
 
   def self.from_dynamic!(d)
     d = Types::Hash[d]
@@ -7474,8 +7474,8 @@ class X2Class < Dry::Struct
       bin:       d["bin"] ? Bin.from_dynamic!(d["bin"]) : nil,
       field:     d["field"] ? Field.from_dynamic!(d["field"]) : nil,
       time_unit: d["timeUnit"],
-      def_type:  d["type"],
-      value:     d["value"] ? ConditionalValueDefValue.from_dynamic!(d["value"]) : nil,
+      def_type:  d.fetch("type"),
+      value:     ConditionalValueDefValue.from_dynamic!(d.fetch("value")),
     )
   end
 
@@ -7490,7 +7490,7 @@ class X2Class < Dry::Struct
       "field"     => field&.to_dynamic,
       "timeUnit"  => time_unit,
       "type"      => def_type,
-      "value"     => value&.to_dynamic,
+      "value"     => value.to_dynamic,
     }
   end
 
@@ -8744,7 +8744,7 @@ class Transform < Dry::Struct
   # predicate](filter.html#one-of-predicate);
   # (3) a [selection predicate](filter.html#selection-predicate);
   # or (4) a logical operand that combines (1), (2), or (3).
-  attribute :filter, Types.Instance(LogicalOperandPredicate).optional
+  attribute :filter, Types.Instance(LogicalOperandPredicate)
 
   # The field for storing the computed formula value.
   #
@@ -8760,7 +8760,7 @@ class Transform < Dry::Struct
 
   # A [expression](types.html#expression) string. Use the variable `datum` to refer to the
   # current data object.
-  attribute :calculate, Types::String.optional
+  attribute :calculate, Types::String
 
   # The default value to use if lookup fails.
   #
@@ -8768,24 +8768,24 @@ class Transform < Dry::Struct
   attribute :transform_default, Types::String.optional
 
   # Secondary data reference.
-  attribute :from, LookupData.optional
+  attribute :from, LookupData
 
   # Key in primary data source.
-  attribute :lookup, Types::String.optional
+  attribute :lookup, Types::String
 
   # An object indicating bin properties, or simply `true` for using default bin parameters.
-  attribute :bin, Types.Instance(Bin).optional
+  attribute :bin, Types.Instance(Bin)
 
   # The data field to bin.
   #
   # The data field to apply time unit.
-  attribute :field, Types::String.optional
+  attribute :field, Types::String
 
   # The timeUnit.
-  attribute :time_unit, Types::TimeUnit.optional
+  attribute :time_unit, Types::TimeUnit
 
   # Array of objects that define fields to aggregate.
-  attribute :aggregate, Types.Array(AggregatedFieldDef).optional
+  attribute :aggregate, Types.Array(AggregatedFieldDef)
 
   # The data fields to group by. If not specified, a single group containing all data objects
   # will be used.
@@ -8794,16 +8794,16 @@ class Transform < Dry::Struct
   def self.from_dynamic!(d)
     d = Types::Hash[d]
     new(
-      filter:            d["filter"] ? LogicalOperandPredicate.from_dynamic!(d["filter"]) : nil,
+      filter:            LogicalOperandPredicate.from_dynamic!(d.fetch("filter")),
       as:                d["as"] ? Style.from_dynamic!(d["as"]) : nil,
-      calculate:         d["calculate"],
+      calculate:         d.fetch("calculate"),
       transform_default: d["default"],
-      from:              d["from"] ? LookupData.from_dynamic!(d["from"]) : nil,
-      lookup:            d["lookup"],
-      bin:               d["bin"] ? Bin.from_dynamic!(d["bin"]) : nil,
-      field:             d["field"],
-      time_unit:         d["timeUnit"],
-      aggregate:         d["aggregate"]&.map { |x| AggregatedFieldDef.from_dynamic!(x) },
+      from:              LookupData.from_dynamic!(d.fetch("from")),
+      lookup:            d.fetch("lookup"),
+      bin:               Bin.from_dynamic!(d.fetch("bin")),
+      field:             d.fetch("field"),
+      time_unit:         d.fetch("timeUnit"),
+      aggregate:         d.fetch("aggregate").map { |x| AggregatedFieldDef.from_dynamic!(x) },
       groupby:           d["groupby"],
     )
   end
@@ -8814,16 +8814,16 @@ class Transform < Dry::Struct
 
   def to_dynamic
     {
-      "filter"    => filter&.to_dynamic,
+      "filter"    => filter.to_dynamic,
       "as"        => as&.to_dynamic,
       "calculate" => calculate,
       "default"   => transform_default,
-      "from"      => from&.to_dynamic,
+      "from"      => from.to_dynamic,
       "lookup"    => lookup,
-      "bin"       => bin&.to_dynamic,
+      "bin"       => bin.to_dynamic,
       "field"     => field,
       "timeUnit"  => time_unit,
-      "aggregate" => aggregate&.map { |x| x.to_dynamic },
+      "aggregate" => aggregate.map { |x| x.to_dynamic },
       "groupby"   => groupby,
     }
   end
@@ -8865,7 +8865,7 @@ class LayerSpec < Dry::Struct
   #
   # __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
   # layering facet specifications is not allowed.
-  attribute :layer, Types.Array(LayerSpec).optional
+  attribute :layer, Types.Array(LayerSpec)
 
   # Name of the visualization for later reference.
   attribute :layer_spec_name, Types::String.optional
@@ -8902,13 +8902,13 @@ class LayerSpec < Dry::Struct
   attribute :width, Types::Double.optional
 
   # A key-value mapping between encoding channels and definition of fields.
-  attribute :encoding, EncodingClass.optional
+  attribute :encoding, EncodingClass
 
   # A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
   # `"line"`,
   # * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
   # object](mark.html#mark-def).
-  attribute :mark, Types.Instance(AnyMark).optional
+  attribute :mark, Types.Instance(AnyMark)
 
   # An object defining properties of geographic projection.
   #
@@ -8925,14 +8925,14 @@ class LayerSpec < Dry::Struct
       data:            d["data"] ? DataClass.from_dynamic!(d["data"]) : nil,
       description:     d["description"],
       height:          d["height"],
-      layer:           d["layer"]&.map { |x| LayerSpec.from_dynamic!(x) },
+      layer:           d.fetch("layer").map { |x| LayerSpec.from_dynamic!(x) },
       layer_spec_name: d["name"],
       resolve:         d["resolve"] ? Resolve.from_dynamic!(d["resolve"]) : nil,
       title:           d["title"] ? Title.from_dynamic!(d["title"]) : nil,
       transform:       d["transform"]&.map { |x| Transform.from_dynamic!(x) },
       width:           d["width"],
-      encoding:        d["encoding"] ? EncodingClass.from_dynamic!(d["encoding"]) : nil,
-      mark:            d["mark"] ? AnyMark.from_dynamic!(d["mark"]) : nil,
+      encoding:        EncodingClass.from_dynamic!(d.fetch("encoding")),
+      mark:            AnyMark.from_dynamic!(d.fetch("mark")),
       projection:      d["projection"] ? Projection.from_dynamic!(d["projection"]) : nil,
       selection:       Types::Hash.optional[d["selection"]]&.map { |k, v| [k, SelectionDef.from_dynamic!(v)] }&.to_h,
     )
@@ -8947,14 +8947,14 @@ class LayerSpec < Dry::Struct
       "data"        => data&.to_dynamic,
       "description" => description,
       "height"      => height,
-      "layer"       => layer&.map { |x| x.to_dynamic },
+      "layer"       => layer.map { |x| x.to_dynamic },
       "name"        => layer_spec_name,
       "resolve"     => resolve&.to_dynamic,
       "title"       => title&.to_dynamic,
       "transform"   => transform&.map { |x| x.to_dynamic },
       "width"       => width,
-      "encoding"    => encoding&.to_dynamic,
-      "mark"        => mark&.to_dynamic,
+      "encoding"    => encoding.to_dynamic,
+      "mark"        => mark.to_dynamic,
       "projection"  => projection&.to_dynamic,
       "selection"   => selection&.map { |k, v| [k, v.to_dynamic] }.to_h,
     }
@@ -9031,7 +9031,7 @@ class Spec < Dry::Struct
   #
   # __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
   # layering facet specifications is not allowed.
-  attribute :layer, Types.Array(LayerSpec).optional
+  attribute :layer, Types.Array(LayerSpec)
 
   # Name of the visualization for later reference.
   attribute :spec_name, Types::String.optional
@@ -9076,13 +9076,13 @@ class Spec < Dry::Struct
   attribute :width, Types::Double.optional
 
   # A key-value mapping between encoding channels and definition of fields.
-  attribute :encoding, EncodingClass.optional
+  attribute :encoding, EncodingClass
 
   # A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
   # `"line"`,
   # * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
   # object](mark.html#mark-def).
-  attribute :mark, Types.Instance(AnyMark).optional
+  attribute :mark, Types.Instance(AnyMark)
 
   # An object defining properties of geographic projection.
   #
@@ -9095,20 +9095,20 @@ class Spec < Dry::Struct
 
   # An object that describes mappings between `row` and `column` channels and their field
   # definitions.
-  attribute :facet, FacetMapping.optional
+  attribute :facet, FacetMapping
 
   # A specification of the view that gets faceted.
-  attribute :spec, Spec.optional
+  attribute :spec, Spec
 
   # An object that describes what fields should be repeated into views that are laid out as a
   # `row` or `column`.
-  attribute :repeat, Repeat.optional
+  attribute :repeat, Repeat
 
   # A list of views that should be concatenated and put into a column.
-  attribute :vconcat, Types.Array(Spec).optional
+  attribute :vconcat, Types.Array(Spec)
 
   # A list of views that should be concatenated and put into a row.
-  attribute :hconcat, Types.Array(Spec).optional
+  attribute :hconcat, Types.Array(Spec)
 
   def self.from_dynamic!(d)
     d = Types::Hash[d]
@@ -9116,21 +9116,21 @@ class Spec < Dry::Struct
       data:        d["data"] ? DataClass.from_dynamic!(d["data"]) : nil,
       description: d["description"],
       height:      d["height"],
-      layer:       d["layer"]&.map { |x| LayerSpec.from_dynamic!(x) },
+      layer:       d.fetch("layer").map { |x| LayerSpec.from_dynamic!(x) },
       spec_name:   d["name"],
       resolve:     d["resolve"] ? Resolve.from_dynamic!(d["resolve"]) : nil,
       title:       d["title"] ? Title.from_dynamic!(d["title"]) : nil,
       transform:   d["transform"]&.map { |x| Transform.from_dynamic!(x) },
       width:       d["width"],
-      encoding:    d["encoding"] ? EncodingClass.from_dynamic!(d["encoding"]) : nil,
-      mark:        d["mark"] ? AnyMark.from_dynamic!(d["mark"]) : nil,
+      encoding:    EncodingClass.from_dynamic!(d.fetch("encoding")),
+      mark:        AnyMark.from_dynamic!(d.fetch("mark")),
       projection:  d["projection"] ? Projection.from_dynamic!(d["projection"]) : nil,
       selection:   Types::Hash.optional[d["selection"]]&.map { |k, v| [k, SelectionDef.from_dynamic!(v)] }&.to_h,
-      facet:       d["facet"] ? FacetMapping.from_dynamic!(d["facet"]) : nil,
-      spec:        d["spec"] ? Spec.from_dynamic!(d["spec"]) : nil,
-      repeat:      d["repeat"] ? Repeat.from_dynamic!(d["repeat"]) : nil,
-      vconcat:     d["vconcat"]&.map { |x| Spec.from_dynamic!(x) },
-      hconcat:     d["hconcat"]&.map { |x| Spec.from_dynamic!(x) },
+      facet:       FacetMapping.from_dynamic!(d.fetch("facet")),
+      spec:        Spec.from_dynamic!(d.fetch("spec")),
+      repeat:      Repeat.from_dynamic!(d.fetch("repeat")),
+      vconcat:     d.fetch("vconcat").map { |x| Spec.from_dynamic!(x) },
+      hconcat:     d.fetch("hconcat").map { |x| Spec.from_dynamic!(x) },
     )
   end
 
@@ -9143,21 +9143,21 @@ class Spec < Dry::Struct
       "data"        => data&.to_dynamic,
       "description" => description,
       "height"      => height,
-      "layer"       => layer&.map { |x| x.to_dynamic },
+      "layer"       => layer.map { |x| x.to_dynamic },
       "name"        => spec_name,
       "resolve"     => resolve&.to_dynamic,
       "title"       => title&.to_dynamic,
       "transform"   => transform&.map { |x| x.to_dynamic },
       "width"       => width,
-      "encoding"    => encoding&.to_dynamic,
-      "mark"        => mark&.to_dynamic,
+      "encoding"    => encoding.to_dynamic,
+      "mark"        => mark.to_dynamic,
       "projection"  => projection&.to_dynamic,
       "selection"   => selection&.map { |k, v| [k, v.to_dynamic] }.to_h,
-      "facet"       => facet&.to_dynamic,
-      "spec"        => spec&.to_dynamic,
-      "repeat"      => repeat&.to_dynamic,
-      "vconcat"     => vconcat&.map { |x| x.to_dynamic },
-      "hconcat"     => hconcat&.map { |x| x.to_dynamic },
+      "facet"       => facet.to_dynamic,
+      "spec"        => spec.to_dynamic,
+      "repeat"      => repeat.to_dynamic,
+      "vconcat"     => vconcat.map { |x| x.to_dynamic },
+      "hconcat"     => hconcat.map { |x| x.to_dynamic },
     }
   end
 
@@ -9199,7 +9199,7 @@ class TopLevel < Dry::Struct
   attribute :description, Types::String.optional
 
   # A key-value mapping between encoding channels and definition of fields.
-  attribute :encoding, EncodingWithFacet.optional
+  attribute :encoding, EncodingWithFacet
 
   # The height of a visualization.
   #
@@ -9224,7 +9224,7 @@ class TopLevel < Dry::Struct
   # `"line"`,
   # * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
   # object](mark.html#mark-def).
-  attribute :mark, Types.Instance(AnyMark).optional
+  attribute :mark, Types.Instance(AnyMark)
 
   # Name of the visualization for later reference.
   attribute :top_level_name, Types::String.optional
@@ -9278,7 +9278,7 @@ class TopLevel < Dry::Struct
   #
   # __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
   # layering facet specifications is not allowed.
-  attribute :layer, Types.Array(LayerSpec).optional
+  attribute :layer, Types.Array(LayerSpec)
 
   # Scale, axis, and legend resolutions for layers.
   #
@@ -9293,20 +9293,20 @@ class TopLevel < Dry::Struct
 
   # An object that describes mappings between `row` and `column` channels and their field
   # definitions.
-  attribute :facet, FacetMapping.optional
+  attribute :facet, FacetMapping
 
   # A specification of the view that gets faceted.
-  attribute :spec, Spec.optional
+  attribute :spec, Spec
 
   # An object that describes what fields should be repeated into views that are laid out as a
   # `row` or `column`.
-  attribute :repeat, Repeat.optional
+  attribute :repeat, Repeat
 
   # A list of views that should be concatenated and put into a column.
-  attribute :vconcat, Types.Array(Spec).optional
+  attribute :vconcat, Types.Array(Spec)
 
   # A list of views that should be concatenated and put into a row.
-  attribute :hconcat, Types.Array(Spec).optional
+  attribute :hconcat, Types.Array(Spec)
 
   def self.from_dynamic!(d)
     d = Types::Hash[d]
@@ -9317,9 +9317,9 @@ class TopLevel < Dry::Struct
       config:         d["config"] ? Config.from_dynamic!(d["config"]) : nil,
       data:           d["data"] ? DataClass.from_dynamic!(d["data"]) : nil,
       description:    d["description"],
-      encoding:       d["encoding"] ? EncodingWithFacet.from_dynamic!(d["encoding"]) : nil,
+      encoding:       EncodingWithFacet.from_dynamic!(d.fetch("encoding")),
       height:         d["height"],
-      mark:           d["mark"] ? AnyMark.from_dynamic!(d["mark"]) : nil,
+      mark:           AnyMark.from_dynamic!(d.fetch("mark")),
       top_level_name: d["name"],
       padding:        d["padding"] ? Padding.from_dynamic!(d["padding"]) : nil,
       projection:     d["projection"] ? Projection.from_dynamic!(d["projection"]) : nil,
@@ -9327,13 +9327,13 @@ class TopLevel < Dry::Struct
       title:          d["title"] ? Title.from_dynamic!(d["title"]) : nil,
       transform:      d["transform"]&.map { |x| Transform.from_dynamic!(x) },
       width:          d["width"],
-      layer:          d["layer"]&.map { |x| LayerSpec.from_dynamic!(x) },
+      layer:          d.fetch("layer").map { |x| LayerSpec.from_dynamic!(x) },
       resolve:        d["resolve"] ? Resolve.from_dynamic!(d["resolve"]) : nil,
-      facet:          d["facet"] ? FacetMapping.from_dynamic!(d["facet"]) : nil,
-      spec:           d["spec"] ? Spec.from_dynamic!(d["spec"]) : nil,
-      repeat:         d["repeat"] ? Repeat.from_dynamic!(d["repeat"]) : nil,
-      vconcat:        d["vconcat"]&.map { |x| Spec.from_dynamic!(x) },
-      hconcat:        d["hconcat"]&.map { |x| Spec.from_dynamic!(x) },
+      facet:          FacetMapping.from_dynamic!(d.fetch("facet")),
+      spec:           Spec.from_dynamic!(d.fetch("spec")),
+      repeat:         Repeat.from_dynamic!(d.fetch("repeat")),
+      vconcat:        d.fetch("vconcat").map { |x| Spec.from_dynamic!(x) },
+      hconcat:        d.fetch("hconcat").map { |x| Spec.from_dynamic!(x) },
     )
   end
 
@@ -9349,9 +9349,9 @@ class TopLevel < Dry::Struct
       "config"      => config&.to_dynamic,
       "data"        => data&.to_dynamic,
       "description" => description,
-      "encoding"    => encoding&.to_dynamic,
+      "encoding"    => encoding.to_dynamic,
       "height"      => height,
-      "mark"        => mark&.to_dynamic,
+      "mark"        => mark.to_dynamic,
       "name"        => top_level_name,
       "padding"     => padding&.to_dynamic,
       "projection"  => projection&.to_dynamic,
@@ -9359,13 +9359,13 @@ class TopLevel < Dry::Struct
       "title"       => title&.to_dynamic,
       "transform"   => transform&.map { |x| x.to_dynamic },
       "width"       => width,
-      "layer"       => layer&.map { |x| x.to_dynamic },
+      "layer"       => layer.map { |x| x.to_dynamic },
       "resolve"     => resolve&.to_dynamic,
-      "facet"       => facet&.to_dynamic,
-      "spec"        => spec&.to_dynamic,
-      "repeat"      => repeat&.to_dynamic,
-      "vconcat"     => vconcat&.map { |x| x.to_dynamic },
-      "hconcat"     => hconcat&.map { |x| x.to_dynamic },
+      "facet"       => facet.to_dynamic,
+      "spec"        => spec.to_dynamic,
+      "repeat"      => repeat.to_dynamic,
+      "vconcat"     => vconcat.map { |x| x.to_dynamic },
+      "hconcat"     => hconcat.map { |x| x.to_dynamic },
     }
   end
 
diff --git a/head/schema-rust/test/inputs/schema/required-in-any-of.schema/default/module_under_test.rs b/head/schema-rust/test/inputs/schema/required-in-any-of.schema/default/module_under_test.rs
new file mode 100644
index 0000000..35f6c9c
--- /dev/null
+++ b/head/schema-rust/test/inputs/schema/required-in-any-of.schema/default/module_under_test.rs
@@ -0,0 +1,26 @@
+// Example code that deserializes and serializes the model.
+// extern crate serde;
+// #[macro_use]
+// extern crate serde_derive;
+// extern crate serde_json;
+//
+// use generated_module::TopLevel;
+//
+// fn main() {
+//     let json = r#"{"answer": 42}"#;
+//     let model: TopLevel = serde_json::from_str(&json).unwrap();
+// }
+
+use serde::{Serialize, Deserialize};
+
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct TopLevel {
+    pub anyof: Anyof,
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct Anyof {
+    pub name: String,
+
+    pub size: Option<String>,
+}
diff --git a/base/schema-rust/test/inputs/schema/vega-lite.schema/default/module_under_test.rs b/head/schema-rust/test/inputs/schema/vega-lite.schema/default/module_under_test.rs
index d192286..103c6c0 100644
--- a/base/schema-rust/test/inputs/schema/vega-lite.schema/default/module_under_test.rs
+++ b/head/schema-rust/test/inputs/schema/vega-lite.schema/default/module_under_test.rs
@@ -48,7 +48,7 @@ pub struct TopLevel {
     pub description: Option<String>,
 
     /// A key-value mapping between encoding channels and definition of fields.
-    pub encoding: Option<EncodingWithFacet>,
+    pub encoding: EncodingWithFacet,
 
     /// The height of a visualization.
     ///
@@ -73,7 +73,7 @@ pub struct TopLevel {
     /// `"line"`,
     /// * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
     /// object](mark.html#mark-def).
-    pub mark: Option<AnyMark>,
+    pub mark: AnyMark,
 
     /// Name of the visualization for later reference.
     pub name: Option<String>,
@@ -127,7 +127,7 @@ pub struct TopLevel {
     ///
     /// __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
     /// layering facet specifications is not allowed.
-    pub layer: Option<Vec<LayerSpec>>,
+    pub layer: Vec<LayerSpec>,
 
     /// Scale, axis, and legend resolutions for layers.
     ///
@@ -142,20 +142,20 @@ pub struct TopLevel {
 
     /// An object that describes mappings between `row` and `column` channels and their field
     /// definitions.
-    pub facet: Option<FacetMapping>,
+    pub facet: FacetMapping,
 
     /// A specification of the view that gets faceted.
-    pub spec: Box<Option<Spec>>,
+    pub spec: Box<Spec>,
 
     /// An object that describes what fields should be repeated into views that are laid out as a
     /// `row` or `column`.
-    pub repeat: Option<Repeat>,
+    pub repeat: Repeat,
 
     /// A list of views that should be concatenated and put into a column.
-    pub vconcat: Option<Vec<Spec>>,
+    pub vconcat: Vec<Spec>,
 
     /// A list of views that should be concatenated and put into a row.
-    pub hconcat: Option<Vec<Spec>>,
+    pub hconcat: Vec<Spec>,
 }
 
 /// Sets how the visualization size should be determined. If a string, should be one of
@@ -1712,7 +1712,7 @@ pub struct VgScheme {
 
     pub extent: Option<Vec<f64>>,
 
-    pub scheme: Option<String>,
+    pub scheme: String,
 
     pub step: Option<f64>,
 }
@@ -2148,7 +2148,7 @@ pub struct VgBinding {
 
     pub input: String,
 
-    pub options: Option<Vec<String>>,
+    pub options: Vec<String>,
 
     pub max: Option<f64>,
 
@@ -2800,16 +2800,16 @@ pub struct Data {
 
     /// An URL from which to load the data set. Use the `format.type` property
     /// to ensure the loaded data is correctly parsed.
-    pub url: Option<String>,
+    pub url: String,
 
     /// The full data set, included inline. This can be an array of objects or primitive values
     /// or a string.
     /// Arrays of primitive values are ingested as objects with a `data` property. Strings are
     /// parsed according to the specified format type.
-    pub values: Option<Values>,
+    pub values: Values,
 
     /// Provide a placeholder name and bind data at runtime.
-    pub name: Option<String>,
+    pub name: String,
 }
 
 /// An object that specifies the format for parsing the data file.
@@ -3050,7 +3050,7 @@ pub struct MarkPropDefWithCondition {
     /// If `true`, default [binning parameters](bin.html) will be applied.
     ///
     /// __Default value:__ `false`
-    pub bin: Option<Bin>,
+    pub bin: Option<ColorBin>,
 
     /// One or more value definition(s) with a selection predicate.
     ///
@@ -3105,10 +3105,10 @@ pub struct MarkPropDefWithCondition {
     /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
     /// [geographic projection](projection.html) is applied.
     #[serde(rename = "type")]
-    pub mark_prop_def_with_condition_type: Option<Type>,
+    pub mark_prop_def_with_condition_type: Type,
 
     /// A constant value in visual domain.
-    pub value: Option<ConditionalPredicateValueDefValue>,
+    pub value: Option<ColorValue>,
 }
 
 /// Aggregation function for the field
@@ -3177,7 +3177,7 @@ pub enum AggregateOp {
 
 #[derive(Debug, Clone, Serialize, Deserialize)]
 #[serde(untagged)]
-pub enum Bin {
+pub enum ColorBin {
     BinParams(BinParams),
 
     Bool(bool),
@@ -3234,7 +3234,7 @@ pub enum ColorCondition {
 
 #[derive(Debug, Clone, Serialize, Deserialize)]
 pub struct ConditionalValueDef {
-    pub test: Option<Box<ConditionalValueDefLogicalOperandPredicate>>,
+    pub test: Box<LogicalOperandPredicate>,
 
     /// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
     /// `0` to `1` for opacity).
@@ -3242,28 +3242,16 @@ pub struct ConditionalValueDef {
 
     /// A [selection name](selection.html), or a series of [composed
     /// selections](selection.html#compose).
-    pub selection: Option<Box<ConditionalValueDefSelectionOperand>>,
-}
-
-/// Filter using a selection name.
-///
-/// A [selection name](selection.html), or a series of [composed
-/// selections](selection.html#compose).
-#[derive(Debug, Clone, Serialize, Deserialize)]
-#[serde(untagged)]
-pub enum SelectionOperandElement {
-    PurpleString(String),
-
-    Selection(Selection),
+    pub selection: Box<SelectionOperand>,
 }
 
 #[derive(Debug, Clone, Serialize, Deserialize)]
 pub struct Selection {
-    pub not: Option<Box<ConditionalValueDefSelectionOperand>>,
+    pub not: Box<SelectionOperand>,
 
-    pub and: Option<Vec<SelectionOperandElement>>,
+    pub and: Vec<Box<SelectionOperand>>,
 
-    pub or: Option<Vec<SelectionOperandElement>>,
+    pub or: Vec<Box<SelectionOperand>>,
 }
 
 /// Filter using a selection name.
@@ -3272,44 +3260,28 @@ pub struct Selection {
 /// selections](selection.html#compose).
 #[derive(Debug, Clone, Serialize, Deserialize)]
 #[serde(untagged)]
-pub enum ConditionalValueDefSelectionOperand {
+pub enum SelectionOperand {
     PurpleString(String),
 
     Selection(Selection),
 }
 
-/// The `filter` property must be one of the predicate definitions:
-/// (1) an [expression](types.html#expression) string,
-/// where `datum` can be used to refer to the current data object;
-/// (2) one of the field predicates: [equal predicate](filter.html#equal-predicate);
-/// [range predicate](filter.html#range-predicate), [one-of
-/// predicate](filter.html#one-of-predicate);
-/// (3) a [selection predicate](filter.html#selection-predicate);
-/// or (4) a logical operand that combines (1), (2), or (3).
-#[derive(Debug, Clone, Serialize, Deserialize)]
-#[serde(untagged)]
-pub enum LogicalOperandPredicateElement {
-    Predicate(Predicate),
-
-    PurpleString(String),
-}
-
 #[derive(Debug, Clone, Serialize, Deserialize)]
 #[serde(rename_all = "camelCase")]
 pub struct Predicate {
-    pub not: Option<Box<ConditionalValueDefLogicalOperandPredicate>>,
+    pub not: Box<LogicalOperandPredicate>,
 
-    pub and: Option<Vec<LogicalOperandPredicateElement>>,
+    pub and: Vec<Box<LogicalOperandPredicate>>,
 
-    pub or: Option<Vec<LogicalOperandPredicateElement>>,
+    pub or: Vec<Box<LogicalOperandPredicate>>,
 
     /// The value that the field should be equal to.
-    pub equal: Option<EqualUnion>,
+    pub equal: Equal,
 
     /// Field to be filtered.
     ///
     /// Field to be filtered
-    pub field: Option<String>,
+    pub field: String,
 
     /// Time unit for the field to be filtered.
     ///
@@ -3318,14 +3290,14 @@ pub struct Predicate {
 
     /// An array of inclusive minimum and maximum values
     /// for a field value of a data item to be included in the filtered data.
-    pub range: Option<Vec<Option<RangeElement>>>,
+    pub range: Vec<Option<RangeElement>>,
 
     /// A set of values that the `field`'s value should be a member of,
     /// for a data item included in the filtered data.
-    pub one_of: Option<Vec<OneOfElement>>,
+    pub one_of: Vec<Equal>,
 
     /// Filter using a selection name.
-    pub selection: Option<Box<ConditionalValueDefSelectionOperand>>,
+    pub selection: Box<SelectionOperand>,
 }
 
 /// The `filter` property must be one of the predicate definitions:
@@ -3338,7 +3310,7 @@ pub struct Predicate {
 /// or (4) a logical operand that combines (1), (2), or (3).
 #[derive(Debug, Clone, Serialize, Deserialize)]
 #[serde(untagged)]
-pub enum ConditionalValueDefLogicalOperandPredicate {
+pub enum LogicalOperandPredicate {
     Predicate(Predicate),
 
     PurpleString(String),
@@ -3347,7 +3319,7 @@ pub enum ConditionalValueDefLogicalOperandPredicate {
 /// The value that the field should be equal to.
 #[derive(Debug, Clone, Serialize, Deserialize)]
 #[serde(untagged)]
-pub enum EqualUnion {
+pub enum Equal {
     Bool(bool),
 
     DateTime(DateTime),
@@ -3425,19 +3397,6 @@ pub enum Month {
     PurpleString(String),
 }
 
-/// The value that the field should be equal to.
-#[derive(Debug, Clone, Serialize, Deserialize)]
-#[serde(untagged)]
-pub enum OneOfElement {
-    Bool(bool),
-
-    DateTime(DateTime),
-
-    Double(f64),
-
-    PurpleString(String),
-}
-
 #[derive(Debug, Clone, Serialize, Deserialize)]
 #[serde(untagged)]
 pub enum RangeElement {
@@ -3565,15 +3524,15 @@ pub enum ConditionalValueDefValue {
 #[derive(Debug, Clone, Serialize, Deserialize)]
 #[serde(rename_all = "camelCase")]
 pub struct ConditionalPredicateMarkPropFieldDefClass {
-    pub test: Option<Box<ConditionalValueDefLogicalOperandPredicate>>,
+    pub test: Box<LogicalOperandPredicate>,
 
     /// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
     /// `0` to `1` for opacity).
-    pub value: Option<ConditionalPredicateValueDefValue>,
+    pub value: ConditionalValueDefValue,
 
     /// A [selection name](selection.html), or a series of [composed
     /// selections](selection.html#compose).
-    pub selection: Option<Box<ConditionalValueDefSelectionOperand>>,
+    pub selection: Box<SelectionOperand>,
 
     /// Aggregation function for the field
     /// (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`).
@@ -3586,7 +3545,7 @@ pub struct ConditionalPredicateMarkPropFieldDefClass {
     /// If `true`, default [binning parameters](bin.html) will be applied.
     ///
     /// __Default value:__ `false`
-    pub bin: Option<Bin>,
+    pub bin: Option<ColorBin>,
 
     /// __Required.__ A string defining the name of the field from which to pull a data value
     /// or an object defining iterated values from the [`repeat`](repeat.html) operator.
@@ -3632,7 +3591,7 @@ pub struct ConditionalPredicateMarkPropFieldDefClass {
     /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
     /// [geographic projection](projection.html) is applied.
     #[serde(rename = "type")]
-    pub conditional_def_type: Option<Type>,
+    pub conditional_def_type: Type,
 }
 
 /// The encoded field's type of measurement (`"quantitative"`, `"temporal"`, `"ordinal"`, or
@@ -3989,7 +3948,7 @@ pub enum DomainUnion {
 
     Enum(Domain),
 
-    UnionArray(Vec<OneOfElement>),
+    UnionArray(Vec<Equal>),
 }
 
 #[derive(Debug, Clone, Serialize, Deserialize)]
@@ -4261,7 +4220,7 @@ pub enum SortEnum {
 /// A constant value in visual domain.
 #[derive(Debug, Clone, Serialize, Deserialize)]
 #[serde(untagged)]
-pub enum ConditionalPredicateValueDefValue {
+pub enum ColorValue {
     Bool(bool),
 
     Double(f64),
@@ -4286,7 +4245,7 @@ pub struct FacetFieldDef {
     /// If `true`, default [binning parameters](bin.html) will be applied.
     ///
     /// __Default value:__ `false`
-    pub bin: Option<Bin>,
+    pub bin: Option<ColorBin>,
 
     /// __Required.__ A string defining the name of the field from which to pull a data value
     /// or an object defining iterated values from the [`repeat`](repeat.html) operator.
@@ -4381,7 +4340,7 @@ pub struct FieldDef {
     /// If `true`, default [binning parameters](bin.html) will be applied.
     ///
     /// __Default value:__ `false`
-    pub bin: Option<Bin>,
+    pub bin: Option<ColorBin>,
 
     /// __Required.__ A string defining the name of the field from which to pull a data value
     /// or an object defining iterated values from the [`repeat`](repeat.html) operator.
@@ -4437,7 +4396,7 @@ pub struct DefWithCondition {
     /// If `true`, default [binning parameters](bin.html) will be applied.
     ///
     /// __Default value:__ `false`
-    pub bin: Option<Bin>,
+    pub bin: Option<ColorBin>,
 
     /// One or more value definition(s) with a selection predicate.
     ///
@@ -4471,10 +4430,10 @@ pub struct DefWithCondition {
     /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
     /// [geographic projection](projection.html) is applied.
     #[serde(rename = "type")]
-    pub def_with_condition_type: Option<Type>,
+    pub def_with_condition_type: Type,
 
     /// A constant value in visual domain.
-    pub value: Option<ConditionalPredicateValueDefValue>,
+    pub value: Option<ColorValue>,
 }
 
 #[derive(Debug, Clone, Serialize, Deserialize)]
@@ -4488,15 +4447,15 @@ pub enum HrefCondition {
 #[derive(Debug, Clone, Serialize, Deserialize)]
 #[serde(rename_all = "camelCase")]
 pub struct ConditionalPredicateFieldDefClass {
-    pub test: Option<Box<ConditionalValueDefLogicalOperandPredicate>>,
+    pub test: Box<LogicalOperandPredicate>,
 
     /// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
     /// `0` to `1` for opacity).
-    pub value: Option<ConditionalPredicateValueDefValue>,
+    pub value: ConditionalValueDefValue,
 
     /// A [selection name](selection.html), or a series of [composed
     /// selections](selection.html#compose).
-    pub selection: Option<Box<ConditionalValueDefSelectionOperand>>,
+    pub selection: Box<SelectionOperand>,
 
     /// Aggregation function for the field
     /// (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`).
@@ -4509,7 +4468,7 @@ pub struct ConditionalPredicateFieldDefClass {
     /// If `true`, default [binning parameters](bin.html) will be applied.
     ///
     /// __Default value:__ `false`
-    pub bin: Option<Bin>,
+    pub bin: Option<ColorBin>,
 
     /// __Required.__ A string defining the name of the field from which to pull a data value
     /// or an object defining iterated values from the [`repeat`](repeat.html) operator.
@@ -4534,7 +4493,7 @@ pub struct ConditionalPredicateFieldDefClass {
     /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
     /// [geographic projection](projection.html) is applied.
     #[serde(rename = "type")]
-    pub conditional_def_type: Option<Type>,
+    pub conditional_def_type: Type,
 }
 
 #[derive(Debug, Clone, Serialize, Deserialize)]
@@ -4559,7 +4518,7 @@ pub struct OrderFieldDef {
     /// If `true`, default [binning parameters](bin.html) will be applied.
     ///
     /// __Default value:__ `false`
-    pub bin: Option<Bin>,
+    pub bin: Option<ColorBin>,
 
     /// __Required.__ A string defining the name of the field from which to pull a data value
     /// or an object defining iterated values from the [`repeat`](repeat.html) operator.
@@ -4620,7 +4579,7 @@ pub struct TextDefWithCondition {
     /// If `true`, default [binning parameters](bin.html) will be applied.
     ///
     /// __Default value:__ `false`
-    pub bin: Option<Bin>,
+    pub bin: Option<ColorBin>,
 
     /// One or more value definition(s) with a selection predicate.
     ///
@@ -4658,10 +4617,10 @@ pub struct TextDefWithCondition {
     /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
     /// [geographic projection](projection.html) is applied.
     #[serde(rename = "type")]
-    pub text_def_with_condition_type: Option<Type>,
+    pub text_def_with_condition_type: Type,
 
     /// A constant value in visual domain.
-    pub value: Option<ConditionalPredicateValueDefValue>,
+    pub value: Option<ColorValue>,
 }
 
 #[derive(Debug, Clone, Serialize, Deserialize)]
@@ -4675,15 +4634,15 @@ pub enum TextCondition {
 #[derive(Debug, Clone, Serialize, Deserialize)]
 #[serde(rename_all = "camelCase")]
 pub struct ConditionalPredicateTextFieldDefClass {
-    pub test: Option<Box<ConditionalValueDefLogicalOperandPredicate>>,
+    pub test: Box<LogicalOperandPredicate>,
 
     /// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
     /// `0` to `1` for opacity).
-    pub value: Option<ConditionalPredicateValueDefValue>,
+    pub value: ConditionalValueDefValue,
 
     /// A [selection name](selection.html), or a series of [composed
     /// selections](selection.html#compose).
-    pub selection: Option<Box<ConditionalValueDefSelectionOperand>>,
+    pub selection: Box<SelectionOperand>,
 
     /// Aggregation function for the field
     /// (e.g., `mean`, `sum`, `median`, `min`, `max`, `count`).
@@ -4696,7 +4655,7 @@ pub struct ConditionalPredicateTextFieldDefClass {
     /// If `true`, default [binning parameters](bin.html) will be applied.
     ///
     /// __Default value:__ `false`
-    pub bin: Option<Bin>,
+    pub bin: Option<ColorBin>,
 
     /// __Required.__ A string defining the name of the field from which to pull a data value
     /// or an object defining iterated values from the [`repeat`](repeat.html) operator.
@@ -4725,7 +4684,7 @@ pub struct ConditionalPredicateTextFieldDefClass {
     /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
     /// [geographic projection](projection.html) is applied.
     #[serde(rename = "type")]
-    pub conditional_def_type: Option<Type>,
+    pub conditional_def_type: Type,
 }
 
 /// X coordinates of the marks, or width of horizontal `"bar"` and `"area"`.
@@ -4753,7 +4712,7 @@ pub struct XClass {
     /// If `true`, default [binning parameters](bin.html) will be applied.
     ///
     /// __Default value:__ `false`
-    pub bin: Option<Bin>,
+    pub bin: Option<ColorBin>,
 
     /// __Required.__ A string defining the name of the field from which to pull a data value
     /// or an object defining iterated values from the [`repeat`](repeat.html) operator.
@@ -4815,11 +4774,11 @@ pub struct XClass {
     /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
     /// [geographic projection](projection.html) is applied.
     #[serde(rename = "type")]
-    pub def_type: Option<Type>,
+    pub def_type: Type,
 
     /// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
     /// `0` to `1` for opacity).
-    pub value: Option<ConditionalPredicateValueDefValue>,
+    pub value: ConditionalValueDefValue,
 }
 
 #[derive(Debug, Clone, Serialize, Deserialize)]
@@ -4997,7 +4956,7 @@ pub struct X2Class {
     /// If `true`, default [binning parameters](bin.html) will be applied.
     ///
     /// __Default value:__ `false`
-    pub bin: Option<Bin>,
+    pub bin: Option<ColorBin>,
 
     /// __Required.__ A string defining the name of the field from which to pull a data value
     /// or an object defining iterated values from the [`repeat`](repeat.html) operator.
@@ -5022,11 +4981,11 @@ pub struct X2Class {
     /// It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
     /// [geographic projection](projection.html) is applied.
     #[serde(rename = "type")]
-    pub def_type: Option<Type>,
+    pub def_type: Type,
 
     /// A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
     /// `0` to `1` for opacity).
-    pub value: Option<ConditionalPredicateValueDefValue>,
+    pub value: ConditionalValueDefValue,
 }
 
 /// An object that describes mappings between `row` and `column` channels and their field
@@ -5072,7 +5031,7 @@ pub struct Spec {
     ///
     /// __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
     /// layering facet specifications is not allowed.
-    pub layer: Option<Vec<LayerSpec>>,
+    pub layer: Vec<LayerSpec>,
 
     /// Name of the visualization for later reference.
     pub name: Option<String>,
@@ -5117,13 +5076,13 @@ pub struct Spec {
     pub width: Option<f64>,
 
     /// A key-value mapping between encoding channels and definition of fields.
-    pub encoding: Option<Encoding>,
+    pub encoding: Encoding,
 
     /// A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
     /// `"line"`,
     /// * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
     /// object](mark.html#mark-def).
-    pub mark: Option<AnyMark>,
+    pub mark: AnyMark,
 
     /// An object defining properties of geographic projection.
     ///
@@ -5136,20 +5095,20 @@ pub struct Spec {
 
     /// An object that describes mappings between `row` and `column` channels and their field
     /// definitions.
-    pub facet: Option<FacetMapping>,
+    pub facet: FacetMapping,
 
     /// A specification of the view that gets faceted.
-    pub spec: Box<Option<Spec>>,
+    pub spec: Box<Spec>,
 
     /// An object that describes what fields should be repeated into views that are laid out as a
     /// `row` or `column`.
-    pub repeat: Option<Repeat>,
+    pub repeat: Repeat,
 
     /// A list of views that should be concatenated and put into a column.
-    pub vconcat: Option<Vec<Spec>>,
+    pub vconcat: Vec<Spec>,
 
     /// A list of views that should be concatenated and put into a row.
-    pub hconcat: Option<Vec<Spec>>,
+    pub hconcat: Vec<Spec>,
 }
 
 /// A key-value mapping between encoding channels and definition of fields.
@@ -5253,7 +5212,7 @@ pub struct LayerSpec {
     ///
     /// __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
     /// layering facet specifications is not allowed.
-    pub layer: Option<Vec<LayerSpec>>,
+    pub layer: Vec<LayerSpec>,
 
     /// Name of the visualization for later reference.
     pub name: Option<String>,
@@ -5290,13 +5249,13 @@ pub struct LayerSpec {
     pub width: Option<f64>,
 
     /// A key-value mapping between encoding channels and definition of fields.
-    pub encoding: Option<Encoding>,
+    pub encoding: Encoding,
 
     /// A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
     /// `"line"`,
     /// * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
     /// object](mark.html#mark-def).
-    pub mark: Option<AnyMark>,
+    pub mark: AnyMark,
 
     /// An object defining properties of geographic projection.
     ///
@@ -5832,7 +5791,7 @@ pub struct Transform {
     /// predicate](filter.html#one-of-predicate);
     /// (3) a [selection predicate](filter.html#selection-predicate);
     /// or (4) a logical operand that combines (1), (2), or (3).
-    pub filter: Option<Box<ConditionalValueDefLogicalOperandPredicate>>,
+    pub filter: Box<LogicalOperandPredicate>,
 
     /// The field for storing the computed formula value.
     ///
@@ -5849,7 +5808,7 @@ pub struct Transform {
 
     /// A [expression](types.html#expression) string. Use the variable `datum` to refer to the
     /// current data object.
-    pub calculate: Option<String>,
+    pub calculate: String,
 
     /// The default value to use if lookup fails.
     ///
@@ -5858,24 +5817,24 @@ pub struct Transform {
     pub transform_default: Option<String>,
 
     /// Secondary data reference.
-    pub from: Option<LookupData>,
+    pub from: LookupData,
 
     /// Key in primary data source.
-    pub lookup: Option<String>,
+    pub lookup: String,
 
     /// An object indicating bin properties, or simply `true` for using default bin parameters.
-    pub bin: Option<Bin>,
+    pub bin: TransformBin,
 
     /// The data field to bin.
     ///
     /// The data field to apply time unit.
-    pub field: Option<String>,
+    pub field: String,
 
     /// The timeUnit.
-    pub time_unit: Option<TimeUnit>,
+    pub time_unit: TimeUnit,
 
     /// Array of objects that define fields to aggregate.
-    pub aggregate: Option<Vec<AggregatedFieldDef>>,
+    pub aggregate: Vec<AggregatedFieldDef>,
 
     /// The data fields to group by. If not specified, a single group containing all data objects
     /// will be used.
@@ -5898,6 +5857,14 @@ pub struct AggregatedFieldDef {
     pub op: AggregateOp,
 }
 
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum TransformBin {
+    BinParams(BinParams),
+
+    Bool(bool),
+}
+
 /// Secondary data reference.
 #[derive(Debug, Clone, Serialize, Deserialize)]
 pub struct LookupData {
diff --git a/head/schema-scala3/test/inputs/schema/required-in-any-of.schema/default/TopLevel.scala b/head/schema-scala3/test/inputs/schema/required-in-any-of.schema/default/TopLevel.scala
new file mode 100644
index 0000000..3216873
--- /dev/null
+++ b/head/schema-scala3/test/inputs/schema/required-in-any-of.schema/default/TopLevel.scala
@@ -0,0 +1,17 @@
+package quicktype
+
+import io.circe.syntax._
+import io.circe._
+import cats.syntax.functor._
+
+// If a union has a null in, then we'll need this too... 
+type NullValue = None.type
+
+case class TopLevel (
+    val anyof : Anyof
+) derives Encoder.AsObject, Decoder
+
+case class Anyof (
+    val name : String,
+    val size : Option[String] = None
+) derives Encoder.AsObject, Decoder
diff --git a/base/schema-scala3/test/inputs/schema/vega-lite.schema/default/TopLevel.scala b/head/schema-scala3/test/inputs/schema/vega-lite.schema/default/TopLevel.scala
index 0eed549..9b786d3 100644
--- a/base/schema-scala3/test/inputs/schema/vega-lite.schema/default/TopLevel.scala
+++ b/head/schema-scala3/test/inputs/schema/vega-lite.schema/default/TopLevel.scala
@@ -53,7 +53,7 @@ case class TopLevel (
     /**
      * A key-value mapping between encoding channels and definition of fields.
      */
-    val encoding : Option[EncodingWithFacet] = None,
+    val encoding : EncodingWithFacet,
 
     /**
      * The height of a visualization.
@@ -82,7 +82,7 @@ case class TopLevel (
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      */
-    val mark : Option[AnyMark] = None,
+    val mark : AnyMark,
 
     /**
      * Name of the visualization for later reference.
@@ -152,7 +152,7 @@ case class TopLevel (
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      */
-    val layer : Option[Seq[LayerSpec]] = None,
+    val layer : Seq[LayerSpec],
 
     /**
      * Scale, axis, and legend resolutions for layers.
@@ -171,28 +171,28 @@ case class TopLevel (
      * An object that describes mappings between `row` and `column` channels and their field
      * definitions.
      */
-    val facet : Option[FacetMapping] = None,
+    val facet : FacetMapping,
 
     /**
      * A specification of the view that gets faceted.
      */
-    val spec : Option[Spec] = None,
+    val spec : Spec,
 
     /**
      * An object that describes what fields should be repeated into views that are laid out as a
      * `row` or `column`.
      */
-    val repeat : Option[Repeat] = None,
+    val repeat : Repeat,
 
     /**
      * A list of views that should be concatenated and put into a column.
      */
-    val vconcat : Option[Seq[Spec]] = None,
+    val vconcat : Seq[Spec],
 
     /**
      * A list of views that should be concatenated and put into a row.
      */
-    val hconcat : Option[Seq[Spec]] = None
+    val hconcat : Seq[Spec]
 ) derives Encoder.AsObject, Decoder
 
 /**
@@ -2353,7 +2353,7 @@ given Encoder[RangeConfigValue] = Encoder.instance {
 case class VGScheme (
     val count : Option[Double] = None,
     val extent : Option[Seq[Double]] = None,
-    val scheme : Option[String] = None,
+    val scheme : String,
     val step : Option[Double] = None
 ) derives Encoder.AsObject, Decoder
 
@@ -2943,7 +2943,7 @@ case class SingleSelectionConfig (
 case class VGBinding (
     val element : Option[String] = None,
     val input : String,
-    val options : Option[Seq[String]] = None,
+    val options : Seq[String],
     val max : Option[Double] = None,
     val min : Option[Double] = None,
     val step : Option[Double] = None
@@ -3848,7 +3848,7 @@ case class Data (
      * An URL from which to load the data set. Use the `format.type` property
      * to ensure the loaded data is correctly parsed.
      */
-    val url : Option[String] = None,
+    val url : String,
 
     /**
      * The full data set, included inline. This can be an array of objects or primitive values
@@ -3856,12 +3856,12 @@ case class Data (
      * Arrays of primitive values are ingested as objects with a `data` property. Strings are
      * parsed according to the specified format type.
      */
-    val values : Option[Values] = None,
+    val values : Values,
 
     /**
      * Provide a placeholder name and bind data at runtime.
      */
-    val name : Option[String] = None
+    val name : String
 ) derives Encoder.AsObject, Decoder
 
 /**
@@ -4248,7 +4248,7 @@ case class MarkPropDefWithCondition (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val `type` : Option[Type] = None,
+    val `type` : Type,
 
     /**
      * A constant value in visual domain.
@@ -4433,7 +4433,7 @@ given Encoder[ColorCondition] = Encoder.instance {
 }
 
 case class ConditionalValueDef (
-    val test : Option[LogicalOperandPredicate] = None,
+    val test : LogicalOperandPredicate,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
@@ -4445,13 +4445,13 @@ case class ConditionalValueDef (
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
-    val selection : Option[SelectionOperand] = None
+    val selection : SelectionOperand
 ) derives Encoder.AsObject, Decoder
 
 case class Selection (
-    val not : Option[SelectionOperand] = None,
-    val and : Option[Seq[SelectionOperand]] = None,
-    val or : Option[Seq[SelectionOperand]] = None
+    val not : SelectionOperand,
+    val and : Seq[SelectionOperand],
+    val or : Seq[SelectionOperand]
 ) derives Encoder.AsObject, Decoder
 
 /**
@@ -4474,21 +4474,21 @@ given Encoder[SelectionOperand] = Encoder.instance {
 }
 
 case class Predicate (
-    val not : Option[LogicalOperandPredicate] = None,
-    val and : Option[Seq[LogicalOperandPredicate]] = None,
-    val or : Option[Seq[LogicalOperandPredicate]] = None,
+    val not : LogicalOperandPredicate,
+    val and : Seq[LogicalOperandPredicate],
+    val or : Seq[LogicalOperandPredicate],
 
     /**
      * The value that the field should be equal to.
      */
-    val equal : Option[Equal] = None,
+    val equal : Equal,
 
     /**
      * Field to be filtered.
      *
      * Field to be filtered
      */
-    val field : Option[String] = None,
+    val field : String,
 
     /**
      * Time unit for the field to be filtered.
@@ -4501,18 +4501,18 @@ case class Predicate (
      * An array of inclusive minimum and maximum values
      * for a field value of a data item to be included in the filtered data.
      */
-    val range : Option[Seq[RangeElement]] = None,
+    val range : Seq[RangeElement],
 
     /**
      * A set of values that the `field`'s value should be a member of,
      * for a data item included in the filtered data.
      */
-    val oneOf : Option[Seq[Equal]] = None,
+    val oneOf : Seq[Equal],
 
     /**
      * Filter using a selection name.
      */
-    val selection : Option[SelectionOperand] = None
+    val selection : SelectionOperand
 ) derives Encoder.AsObject, Decoder
 
 /**
@@ -4827,19 +4827,19 @@ given Encoder[ConditionalValueDefValue] = Encoder.instance {
 }
 
 case class ConditionalPredicateMarkPropFieldDefClass (
-    val test : Option[LogicalOperandPredicate] = None,
+    val test : LogicalOperandPredicate,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    val value : Option[ConditionalValueDefValue] = None,
+    val value : ConditionalValueDefValue,
 
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
-    val selection : Option[SelectionOperand] = None,
+    val selection : SelectionOperand,
 
     /**
      * Aggregation function for the field
@@ -4913,7 +4913,7 @@ case class ConditionalPredicateMarkPropFieldDefClass (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val `type` : Option[Type] = None
+    val `type` : Type
 ) derives Encoder.AsObject, Decoder
 
 /**
@@ -5965,7 +5965,7 @@ case class DefWithCondition (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val `type` : Option[Type] = None,
+    val `type` : Type,
 
     /**
      * A constant value in visual domain.
@@ -5987,19 +5987,19 @@ given Encoder[HrefCondition] = Encoder.instance {
 }
 
 case class ConditionalPredicateFieldDefClass (
-    val test : Option[LogicalOperandPredicate] = None,
+    val test : LogicalOperandPredicate,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    val value : Option[ConditionalValueDefValue] = None,
+    val value : ConditionalValueDefValue,
 
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
-    val selection : Option[SelectionOperand] = None,
+    val selection : SelectionOperand,
 
     /**
      * Aggregation function for the field
@@ -6046,7 +6046,7 @@ case class ConditionalPredicateFieldDefClass (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val `type` : Option[Type] = None
+    val `type` : Type
 ) derives Encoder.AsObject, Decoder
 
 type Order = Seq[OrderFieldDef] | OrderFieldDef
@@ -6197,7 +6197,7 @@ case class TextDefWithCondition (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val `type` : Option[Type] = None,
+    val `type` : Type,
 
     /**
      * A constant value in visual domain.
@@ -6219,19 +6219,19 @@ given Encoder[TextCondition] = Encoder.instance {
 }
 
 case class ConditionalPredicateTextFieldDefClass (
-    val test : Option[LogicalOperandPredicate] = None,
+    val test : LogicalOperandPredicate,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    val value : Option[ConditionalValueDefValue] = None,
+    val value : ConditionalValueDefValue,
 
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
-    val selection : Option[SelectionOperand] = None,
+    val selection : SelectionOperand,
 
     /**
      * Aggregation function for the field
@@ -6284,7 +6284,7 @@ case class ConditionalPredicateTextFieldDefClass (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val `type` : Option[Type] = None
+    val `type` : Type
 ) derives Encoder.AsObject, Decoder
 
 /**
@@ -6391,13 +6391,13 @@ case class XClass (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val `type` : Option[Type] = None,
+    val `type` : Type,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    val value : Option[ConditionalValueDefValue] = None
+    val value : ConditionalValueDefValue
 ) derives Encoder.AsObject, Decoder
 
 case class Axis (
@@ -6656,13 +6656,13 @@ case class X2Class (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val `type` : Option[Type] = None,
+    val `type` : Type,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    val value : Option[ConditionalValueDefValue] = None
+    val value : ConditionalValueDefValue
 ) derives Encoder.AsObject, Decoder
 
 /**
@@ -6722,7 +6722,7 @@ case class Spec (
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      */
-    val layer : Option[Seq[LayerSpec]] = None,
+    val layer : Seq[LayerSpec],
 
     /**
      * Name of the visualization for later reference.
@@ -6779,7 +6779,7 @@ case class Spec (
     /**
      * A key-value mapping between encoding channels and definition of fields.
      */
-    val encoding : Option[Encoding] = None,
+    val encoding : Encoding,
 
     /**
      * A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
@@ -6787,7 +6787,7 @@ case class Spec (
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      */
-    val mark : Option[AnyMark] = None,
+    val mark : AnyMark,
 
     /**
      * An object defining properties of geographic projection.
@@ -6806,28 +6806,28 @@ case class Spec (
      * An object that describes mappings between `row` and `column` channels and their field
      * definitions.
      */
-    val facet : Option[FacetMapping] = None,
+    val facet : FacetMapping,
 
     /**
      * A specification of the view that gets faceted.
      */
-    val spec : Option[Spec] = None,
+    val spec : Spec,
 
     /**
      * An object that describes what fields should be repeated into views that are laid out as a
      * `row` or `column`.
      */
-    val repeat : Option[Repeat] = None,
+    val repeat : Repeat,
 
     /**
      * A list of views that should be concatenated and put into a column.
      */
-    val vconcat : Option[Seq[Spec]] = None,
+    val vconcat : Seq[Spec],
 
     /**
      * A list of views that should be concatenated and put into a row.
      */
-    val hconcat : Option[Seq[Spec]] = None
+    val hconcat : Seq[Spec]
 ) derives Encoder.AsObject, Decoder
 
 /**
@@ -6967,7 +6967,7 @@ case class LayerSpec (
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      */
-    val layer : Option[Seq[LayerSpec]] = None,
+    val layer : Seq[LayerSpec],
 
     /**
      * Name of the visualization for later reference.
@@ -7016,7 +7016,7 @@ case class LayerSpec (
     /**
      * A key-value mapping between encoding channels and definition of fields.
      */
-    val encoding : Option[Encoding] = None,
+    val encoding : Encoding,
 
     /**
      * A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
@@ -7024,7 +7024,7 @@ case class LayerSpec (
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      */
-    val mark : Option[AnyMark] = None,
+    val mark : AnyMark,
 
     /**
      * An object defining properties of geographic projection.
@@ -7703,7 +7703,7 @@ case class Transform (
      * (3) a [selection predicate](filter.html#selection-predicate);
      * or (4) a logical operand that combines (1), (2), or (3).
      */
-    val filter : Option[LogicalOperandPredicate] = None,
+    val filter : LogicalOperandPredicate,
 
     /**
      * The field for storing the computed formula value.
@@ -7723,7 +7723,7 @@ case class Transform (
      * A [expression](types.html#expression) string. Use the variable `datum` to refer to the
      * current data object.
      */
-    val calculate : Option[String] = None,
+    val calculate : String,
 
     /**
      * The default value to use if lookup fails.
@@ -7735,34 +7735,34 @@ case class Transform (
     /**
      * Secondary data reference.
      */
-    val from : Option[LookupData] = None,
+    val from : LookupData,
 
     /**
      * Key in primary data source.
      */
-    val lookup : Option[String] = None,
+    val lookup : String,
 
     /**
      * An object indicating bin properties, or simply `true` for using default bin parameters.
      */
-    val bin : Option[Bin] = None,
+    val bin : Bin,
 
     /**
      * The data field to bin.
      *
      * The data field to apply time unit.
      */
-    val field : Option[String] = None,
+    val field : String,
 
     /**
      * The timeUnit.
      */
-    val timeUnit : Option[TimeUnit] = None,
+    val timeUnit : TimeUnit,
 
     /**
      * Array of objects that define fields to aggregate.
      */
-    val aggregate : Option[Seq[AggregatedFieldDef]] = None,
+    val aggregate : Seq[AggregatedFieldDef],
 
     /**
      * The data fields to group by. If not specified, a single group containing all data objects
diff --git a/head/schema-scala3-upickle/test/inputs/schema/required-in-any-of.schema/default/TopLevel.scala b/head/schema-scala3-upickle/test/inputs/schema/required-in-any-of.schema/default/TopLevel.scala
new file mode 100644
index 0000000..8471613
--- /dev/null
+++ b/head/schema-scala3-upickle/test/inputs/schema/required-in-any-of.schema/default/TopLevel.scala
@@ -0,0 +1,75 @@
+package quicktype
+
+// Custom pickler so that missing keys and JSON nulls both read as None,
+// and None is left out when writing (upickle's default for Option is a
+// JSON array).
+object OptionPickler extends upickle.AttributeTagged:
+    import upickle.default.Writer
+    import upickle.default.Reader
+    override implicit def OptionWriter[T: Writer]: Writer[Option[T]] =
+        implicitly[Writer[T]].comap[Option[T]] {
+            case None => null.asInstanceOf[T]
+            case Some(x) => x
+        }
+
+    override implicit def OptionReader[T: Reader]: Reader[Option[T]] = {
+        new Reader.Delegate[Any, Option[T]](implicitly[Reader[T]].map(Some(_))){
+        override def visitNull(index: Int) = None
+        }
+    }
+end OptionPickler
+
+// If a union has a null in, then we'll need this too...
+type NullValue = None.type
+given OptionPickler.ReadWriter[NullValue] = OptionPickler.readwriter[ujson.Value].bimap[NullValue](
+    _ => ujson.Null,
+    json => if json.isNull then None else throw new upickle.core.Abort("not null")
+)
+
+object JsonExt:
+    val valueReader = OptionPickler.readwriter[ujson.Value]
+
+    // upickle's built-in primitive readers are lenient -- the numeric and
+    // boolean readers accept strings, and the string reader accepts
+    // numbers and booleans -- so untagged unions need strict readers to
+    // pick the right member.
+    val strictString: OptionPickler.Reader[String] = valueReader.map {
+        case ujson.Str(s) => s
+        case json => throw new upickle.core.Abort("expected string, got " + json)
+    }
+    val strictLong: OptionPickler.Reader[Long] = valueReader.map {
+        case ujson.Num(n) if n.isWhole => n.toLong
+        case json => throw new upickle.core.Abort("expected integer, got " + json)
+    }
+    val strictDouble: OptionPickler.Reader[Double] = valueReader.map {
+        case ujson.Num(n) => n
+        case json => throw new upickle.core.Abort("expected number, got " + json)
+    }
+    val strictBoolean: OptionPickler.Reader[Boolean] = valueReader.map {
+        case ujson.Bool(b) => b
+        case json => throw new upickle.core.Abort("expected boolean, got " + json)
+    }
+
+    def badMerge[T](r1: => OptionPickler.Reader[?], rest: OptionPickler.Reader[?]*): OptionPickler.Reader[T] = valueReader.map { json =>
+        var t: T | Null = null
+        val stack       = Vector.newBuilder[Throwable]
+        (r1 +: rest).foreach { reader =>
+            if t == null then
+            try
+                t = OptionPickler.read[T](json, trace = true)(using reader.asInstanceOf[OptionPickler.Reader[T]])
+            catch
+                case exc => stack += exc
+        }
+        if t != null then t.nn else throw new Exception(json.toString(), stack.result().headOption.getOrElse(null))
+    }
+end JsonExt
+
+
+case class TopLevel (
+    val anyof : Anyof
+) derives OptionPickler.ReadWriter
+
+case class Anyof (
+    val name : String,
+    val size : Option[String] = None
+) derives OptionPickler.ReadWriter
diff --git a/base/schema-scala3-upickle/test/inputs/schema/vega-lite.schema/default/TopLevel.scala b/head/schema-scala3-upickle/test/inputs/schema/vega-lite.schema/default/TopLevel.scala
index 834ad3b..562a9c9 100644
--- a/base/schema-scala3-upickle/test/inputs/schema/vega-lite.schema/default/TopLevel.scala
+++ b/head/schema-scala3-upickle/test/inputs/schema/vega-lite.schema/default/TopLevel.scala
@@ -111,7 +111,7 @@ case class TopLevel (
     /**
      * A key-value mapping between encoding channels and definition of fields.
      */
-    val encoding : Option[EncodingWithFacet] = None,
+    val encoding : EncodingWithFacet,
 
     /**
      * The height of a visualization.
@@ -140,7 +140,7 @@ case class TopLevel (
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      */
-    val mark : Option[AnyMark] = None,
+    val mark : AnyMark,
 
     /**
      * Name of the visualization for later reference.
@@ -210,7 +210,7 @@ case class TopLevel (
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      */
-    val layer : Option[Seq[LayerSpec]] = None,
+    val layer : Seq[LayerSpec],
 
     /**
      * Scale, axis, and legend resolutions for layers.
@@ -229,28 +229,28 @@ case class TopLevel (
      * An object that describes mappings between `row` and `column` channels and their field
      * definitions.
      */
-    val facet : Option[FacetMapping] = None,
+    val facet : FacetMapping,
 
     /**
      * A specification of the view that gets faceted.
      */
-    val spec : Option[Spec] = None,
+    val spec : Spec,
 
     /**
      * An object that describes what fields should be repeated into views that are laid out as a
      * `row` or `column`.
      */
-    val repeat : Option[Repeat] = None,
+    val repeat : Repeat,
 
     /**
      * A list of views that should be concatenated and put into a column.
      */
-    val vconcat : Option[Seq[Spec]] = None,
+    val vconcat : Seq[Spec],
 
     /**
      * A list of views that should be concatenated and put into a row.
      */
-    val hconcat : Option[Seq[Spec]] = None
+    val hconcat : Seq[Spec]
 ) derives OptionPickler.ReadWriter
 
 /**
@@ -2432,7 +2432,7 @@ given unionWriterRangeConfigValue: OptionPickler.Writer[RangeConfigValue] = Opti
 case class VGScheme (
     val count : Option[Double] = None,
     val extent : Option[Seq[Double]] = None,
-    val scheme : Option[String] = None,
+    val scheme : String,
     val step : Option[Double] = None
 ) derives OptionPickler.ReadWriter
 
@@ -3029,7 +3029,7 @@ case class SingleSelectionConfig (
 case class VGBinding (
     val element : Option[String] = None,
     val input : String,
-    val options : Option[Seq[String]] = None,
+    val options : Seq[String],
     val max : Option[Double] = None,
     val min : Option[Double] = None,
     val step : Option[Double] = None
@@ -3940,7 +3940,7 @@ case class Data (
      * An URL from which to load the data set. Use the `format.type` property
      * to ensure the loaded data is correctly parsed.
      */
-    val url : Option[String] = None,
+    val url : String,
 
     /**
      * The full data set, included inline. This can be an array of objects or primitive values
@@ -3948,12 +3948,12 @@ case class Data (
      * Arrays of primitive values are ingested as objects with a `data` property. Strings are
      * parsed according to the specified format type.
      */
-    val values : Option[Values] = None,
+    val values : Values,
 
     /**
      * Provide a placeholder name and bind data at runtime.
      */
-    val name : Option[String] = None
+    val name : String
 ) derives OptionPickler.ReadWriter
 
 /**
@@ -4341,7 +4341,7 @@ case class MarkPropDefWithCondition (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val `type` : Option[Type] = None,
+    val `type` : Type,
 
     /**
      * A constant value in visual domain.
@@ -4526,7 +4526,7 @@ given unionWriterColorCondition: OptionPickler.Writer[ColorCondition] = OptionPi
 }
 
 case class ConditionalValueDef (
-    val test : Option[LogicalOperandPredicate] = None,
+    val test : LogicalOperandPredicate,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
@@ -4538,13 +4538,13 @@ case class ConditionalValueDef (
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
-    val selection : Option[SelectionOperand] = None
+    val selection : SelectionOperand
 ) derives OptionPickler.ReadWriter
 
 case class Selection (
-    val not : Option[SelectionOperand] = None,
-    val and : Option[Seq[SelectionOperand]] = None,
-    val or : Option[Seq[SelectionOperand]] = None
+    val not : SelectionOperand,
+    val and : Seq[SelectionOperand],
+    val or : Seq[SelectionOperand]
 ) derives OptionPickler.ReadWriter
 
 /**
@@ -4566,21 +4566,21 @@ given unionWriterSelectionOperand: OptionPickler.Writer[SelectionOperand] = Opti
 }
 
 case class Predicate (
-    val not : Option[LogicalOperandPredicate] = None,
-    val and : Option[Seq[LogicalOperandPredicate]] = None,
-    val or : Option[Seq[LogicalOperandPredicate]] = None,
+    val not : LogicalOperandPredicate,
+    val and : Seq[LogicalOperandPredicate],
+    val or : Seq[LogicalOperandPredicate],
 
     /**
      * The value that the field should be equal to.
      */
-    val equal : Option[Equal] = None,
+    val equal : Equal,
 
     /**
      * Field to be filtered.
      *
      * Field to be filtered
      */
-    val field : Option[String] = None,
+    val field : String,
 
     /**
      * Time unit for the field to be filtered.
@@ -4593,18 +4593,18 @@ case class Predicate (
      * An array of inclusive minimum and maximum values
      * for a field value of a data item to be included in the filtered data.
      */
-    val range : Option[Seq[RangeElement]] = None,
+    val range : Seq[RangeElement],
 
     /**
      * A set of values that the `field`'s value should be a member of,
      * for a data item included in the filtered data.
      */
-    val oneOf : Option[Seq[Equal]] = None,
+    val oneOf : Seq[Equal],
 
     /**
      * Filter using a selection name.
      */
-    val selection : Option[SelectionOperand] = None
+    val selection : SelectionOperand
 ) derives OptionPickler.ReadWriter
 
 /**
@@ -4917,19 +4917,19 @@ given unionWriterConditionalValueDefValue: OptionPickler.Writer[ConditionalValue
 }
 
 case class ConditionalPredicateMarkPropFieldDefClass (
-    val test : Option[LogicalOperandPredicate] = None,
+    val test : LogicalOperandPredicate,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    val value : Option[ConditionalValueDefValue] = None,
+    val value : ConditionalValueDefValue,
 
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
-    val selection : Option[SelectionOperand] = None,
+    val selection : SelectionOperand,
 
     /**
      * Aggregation function for the field
@@ -5003,7 +5003,7 @@ case class ConditionalPredicateMarkPropFieldDefClass (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val `type` : Option[Type] = None
+    val `type` : Type
 ) derives OptionPickler.ReadWriter
 
 /**
@@ -6062,7 +6062,7 @@ case class DefWithCondition (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val `type` : Option[Type] = None,
+    val `type` : Type,
 
     /**
      * A constant value in visual domain.
@@ -6083,19 +6083,19 @@ given unionWriterHrefCondition: OptionPickler.Writer[HrefCondition] = OptionPick
 }
 
 case class ConditionalPredicateFieldDefClass (
-    val test : Option[LogicalOperandPredicate] = None,
+    val test : LogicalOperandPredicate,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    val value : Option[ConditionalValueDefValue] = None,
+    val value : ConditionalValueDefValue,
 
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
-    val selection : Option[SelectionOperand] = None,
+    val selection : SelectionOperand,
 
     /**
      * Aggregation function for the field
@@ -6142,7 +6142,7 @@ case class ConditionalPredicateFieldDefClass (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val `type` : Option[Type] = None
+    val `type` : Type
 ) derives OptionPickler.ReadWriter
 
 type Order = Seq[OrderFieldDef] | OrderFieldDef
@@ -6292,7 +6292,7 @@ case class TextDefWithCondition (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val `type` : Option[Type] = None,
+    val `type` : Type,
 
     /**
      * A constant value in visual domain.
@@ -6313,19 +6313,19 @@ given unionWriterTextCondition: OptionPickler.Writer[TextCondition] = OptionPick
 }
 
 case class ConditionalPredicateTextFieldDefClass (
-    val test : Option[LogicalOperandPredicate] = None,
+    val test : LogicalOperandPredicate,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    val value : Option[ConditionalValueDefValue] = None,
+    val value : ConditionalValueDefValue,
 
     /**
      * A [selection name](selection.html), or a series of [composed
      * selections](selection.html#compose).
      */
-    val selection : Option[SelectionOperand] = None,
+    val selection : SelectionOperand,
 
     /**
      * Aggregation function for the field
@@ -6378,7 +6378,7 @@ case class ConditionalPredicateTextFieldDefClass (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val `type` : Option[Type] = None
+    val `type` : Type
 ) derives OptionPickler.ReadWriter
 
 /**
@@ -6485,13 +6485,13 @@ case class XClass (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val `type` : Option[Type] = None,
+    val `type` : Type,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    val value : Option[ConditionalValueDefValue] = None
+    val value : ConditionalValueDefValue
 ) derives OptionPickler.ReadWriter
 
 case class Axis (
@@ -6749,13 +6749,13 @@ case class X2Class (
      * It can also be a geo type (`"latitude"`, `"longitude"`, and `"geojson"`) when a
      * [geographic projection](projection.html) is applied.
      */
-    val `type` : Option[Type] = None,
+    val `type` : Type,
 
     /**
      * A constant value in visual domain (e.g., `"red"` / "#0099ff" for color, values between
      * `0` to `1` for opacity).
      */
-    val value : Option[ConditionalValueDefValue] = None
+    val value : ConditionalValueDefValue
 ) derives OptionPickler.ReadWriter
 
 /**
@@ -6815,7 +6815,7 @@ case class Spec (
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      */
-    val layer : Option[Seq[LayerSpec]] = None,
+    val layer : Seq[LayerSpec],
 
     /**
      * Name of the visualization for later reference.
@@ -6872,7 +6872,7 @@ case class Spec (
     /**
      * A key-value mapping between encoding channels and definition of fields.
      */
-    val encoding : Option[Encoding] = None,
+    val encoding : Encoding,
 
     /**
      * A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
@@ -6880,7 +6880,7 @@ case class Spec (
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      */
-    val mark : Option[AnyMark] = None,
+    val mark : AnyMark,
 
     /**
      * An object defining properties of geographic projection.
@@ -6899,28 +6899,28 @@ case class Spec (
      * An object that describes mappings between `row` and `column` channels and their field
      * definitions.
      */
-    val facet : Option[FacetMapping] = None,
+    val facet : FacetMapping,
 
     /**
      * A specification of the view that gets faceted.
      */
-    val spec : Option[Spec] = None,
+    val spec : Spec,
 
     /**
      * An object that describes what fields should be repeated into views that are laid out as a
      * `row` or `column`.
      */
-    val repeat : Option[Repeat] = None,
+    val repeat : Repeat,
 
     /**
      * A list of views that should be concatenated and put into a column.
      */
-    val vconcat : Option[Seq[Spec]] = None,
+    val vconcat : Seq[Spec],
 
     /**
      * A list of views that should be concatenated and put into a row.
      */
-    val hconcat : Option[Seq[Spec]] = None
+    val hconcat : Seq[Spec]
 ) derives OptionPickler.ReadWriter
 
 /**
@@ -7060,7 +7060,7 @@ case class LayerSpec (
      * __Note__: Specifications inside `layer` cannot use `row` and `column` channels as
      * layering facet specifications is not allowed.
      */
-    val layer : Option[Seq[LayerSpec]] = None,
+    val layer : Seq[LayerSpec],
 
     /**
      * Name of the visualization for later reference.
@@ -7109,7 +7109,7 @@ case class LayerSpec (
     /**
      * A key-value mapping between encoding channels and definition of fields.
      */
-    val encoding : Option[Encoding] = None,
+    val encoding : Encoding,
 
     /**
      * A string describing the mark type (one of `"bar"`, `"circle"`, `"square"`, `"tick"`,
@@ -7117,7 +7117,7 @@ case class LayerSpec (
      * * `"area"`, `"point"`, `"rule"`, `"geoshape"`, and `"text"`) or a [mark definition
      * object](mark.html#mark-def).
      */
-    val mark : Option[AnyMark] = None,
+    val mark : AnyMark,
 
     /**
      * An object defining properties of geographic projection.
@@ -7798,7 +7798,7 @@ case class Transform (
      * (3) a [selection predicate](filter.html#selection-predicate);
      * or (4) a logical operand that combines (1), (2), or (3).
      */
-    val filter : Option[LogicalOperandPredicate] = None,
+    val filter : LogicalOperandPredicate,
 
     /**
      * The field for storing the computed formula value.
@@ -7818,7 +7818,7 @@ case class Transform (
      * A [expression](types.html#expression) string. Use the variable `datum` to refer to the
      * current data object.
      */
-    val calculate : Option[String] = None,
+    val calculate : String,
 
     /**
      * The default value to use if lookup fails.
@@ -7830,34 +7830,34 @@ case class Transform (
     /**
      * Secondary data reference.
      */
-    val from : Option[LookupData] = None,
+    val from : LookupData,
 
     /**
      * Key in primary data source.
      */
-    val lookup : Option[String] = None,
+    val lookup : String,
 
     /**
      * An object indicating bin properties, or simply `true` for using default bin parameters.
      */
-    val bin : Option[Bin] = None,
+    val bin : Bin,
 
     /**
      * The data field to bin.
      *
      * The data field to apply time unit.
      */
-    val field : Option[String] = None,
+    val field : String,
 
     /**
      * The timeUnit.
      */
-    val timeUnit : Option[TimeUnit] = None,
+    val timeUnit : TimeUnit,
 
     /**
      * Array of objects that define fields to aggregate.
      */
-    val aggregate : Option[Seq[AggregatedFieldDef]] = None,
+    val aggregate : Seq[AggregatedFieldDef],
 
     /**
      * The data fields to group by. If not specified, a single group containing all data objects
diff --git a/head/schema-schema/test/inputs/schema/required-in-any-of.schema/default/TopLevel.schema b/head/schema-schema/test/inputs/schema/required-in-any-of.schema/default/TopLevel.schema
new file mode 100644
index 0000000..7334732
--- /dev/null
+++ b/head/schema-schema/test/inputs/schema/required-in-any-of.schema/default/TopLevel.schema
@@ -0,0 +1,35 @@
+{
+    "$schema": "http://json-schema.org/draft-06/schema#",
+    "$ref": "#/definitions/TopLevel",
+    "definitions": {
+        "TopLevel": {
+            "type": "object",
+            "additionalProperties": false,
+            "properties": {
+                "anyof": {
+                    "$ref": "#/definitions/Anyof"
+                }
+            },
+            "required": [
+                "anyof"
+            ],
+            "title": "TopLevel"
+        },
+        "Anyof": {
+            "type": "object",
+            "additionalProperties": false,
+            "properties": {
+                "name": {
+                    "type": "string"
+                },
+                "size": {
+                    "type": "string"
+                }
+            },
+            "required": [
+                "name"
+            ],
+            "title": "Anyof"
+        }
+    }
+}
diff --git a/base/schema-schema/test/inputs/schema/vega-lite.schema/default/TopLevel.schema b/head/schema-schema/test/inputs/schema/vega-lite.schema/default/TopLevel.schema
index acaeea5..e94a33b 100644
--- a/base/schema-schema/test/inputs/schema/vega-lite.schema/default/TopLevel.schema
+++ b/head/schema-schema/test/inputs/schema/vega-lite.schema/default/TopLevel.schema
@@ -114,7 +114,16 @@
                     "description": "A list of views that should be concatenated and put into a row."
                 }
             },
-            "required": [],
+            "required": [
+                "encoding",
+                "facet",
+                "hconcat",
+                "layer",
+                "mark",
+                "repeat",
+                "spec",
+                "vconcat"
+            ],
             "title": "TopLevel"
         },
         "AutoSizeParams": {
@@ -1306,7 +1315,10 @@
                     "type": "number"
                 }
             },
-            "required": [],
+            "required": [
+                "scheme",
+                "step"
+            ],
             "title": "RangeConfigValueVGScheme"
         },
         "ScaleConfig": {
@@ -2187,7 +2199,11 @@
                     "description": "Provide a placeholder name and bind data at runtime."
                 }
             },
-            "required": [],
+            "required": [
+                "name",
+                "url",
+                "values"
+            ],
             "title": "Data",
             "description": "An object describing the data source\nSecondary data source to lookup in."
         },
@@ -2341,7 +2357,9 @@
                     "description": "A constant value in visual domain."
                 }
             },
-            "required": [],
+            "required": [
+                "type"
+            ],
             "title": "MarkPropDefWithCondition",
             "description": "Color of the marks – either fill or stroke color based on mark type.\nBy default, `color` represents fill color for `\"area\"`, `\"bar\"`, `\"tick\"`,\n`\"text\"`, `\"circle\"`, and `\"square\"` / stroke color for `\"line\"` and `\"point\"`.\n\n__Default value:__ If undefined, the default color depends on [mark config](config.html#mark)'s `color` property.\n\n_Note:_ See the scale documentation for more information about customizing [color scheme](scale.html#scheme).\nOpacity of the marks – either can be a value or a range.\n\n__Default value:__ If undefined, the default opacity depends on [mark config](config.html#mark)'s `opacity` property.\nFor `point` marks the supported values are\n`\"circle\"` (default), `\"square\"`, `\"cross\"`, `\"diamond\"`, `\"triangle-up\"`,\nor `\"triangle-down\"`, or else a custom SVG path string.\nFor `geoshape` marks it should be a field definition of the geojson data\n\n__Default value:__ If undefined, the default shape depends on [mark config](config.html#point-config)'s `shape` property.\nSize of the mark.\n- For `\"point\"`, `\"square\"` and `\"circle\"`, – the symbol size, or pixel area of the mark.\n- For `\"bar\"` and `\"tick\"` – the bar and tick's size.\n- For `\"text\"` – the text's font size.\n- Size is currently unsupported for `\"line\"`, `\"area\"`, and `\"rect\"`.\nA FieldDef with Condition<ValueDef>\n{\n   condition: {value: ...},\n   field: ...,\n   ...\n}\nA ValueDef with Condition<ValueDef | FieldDef>\n{\n   condition: {field: ...} | {value: ...},\n   value: ...,\n}"
         },
@@ -2417,6 +2435,8 @@
                 }
             },
             "required": [
+                "selection",
+                "test",
                 "value"
             ],
             "title": "ConditionalValueDef"
@@ -2476,7 +2496,12 @@
                     "description": "The encoded field's type of measurement (`\"quantitative\"`, `\"temporal\"`, `\"ordinal\"`, or\n`\"nominal\"`).\nIt can also be a geo type (`\"latitude\"`, `\"longitude\"`, and `\"geojson\"`) when a\n[geographic projection](projection.html) is applied."
                 }
             },
-            "required": [],
+            "required": [
+                "selection",
+                "test",
+                "type",
+                "value"
+            ],
             "title": "ConditionalPredicateMarkPropFieldDefClass"
         },
         "Selection": {
@@ -2499,7 +2524,11 @@
                     }
                 }
             },
-            "required": [],
+            "required": [
+                "and",
+                "not",
+                "or"
+            ],
             "title": "Selection"
         },
         "Predicate": {
@@ -2554,7 +2583,16 @@
                     "description": "Filter using a selection name."
                 }
             },
-            "required": [],
+            "required": [
+                "and",
+                "equal",
+                "field",
+                "not",
+                "oneOf",
+                "or",
+                "range",
+                "selection"
+            ],
             "title": "Predicate"
         },
         "DateTime": {
@@ -3019,7 +3057,9 @@
                     "description": "A constant value in visual domain."
                 }
             },
-            "required": [],
+            "required": [
+                "type"
+            ],
             "title": "DefWithCondition",
             "description": "A URL to load upon mouse click.\nA FieldDef with Condition<ValueDef>\n{\n   condition: {value: ...},\n   field: ...,\n   ...\n}\nA ValueDef with Condition<ValueDef | FieldDef>\n{\n   condition: {field: ...} | {value: ...},\n   value: ...,\n}"
         },
@@ -3059,7 +3099,12 @@
                     "description": "The encoded field's type of measurement (`\"quantitative\"`, `\"temporal\"`, `\"ordinal\"`, or\n`\"nominal\"`).\nIt can also be a geo type (`\"latitude\"`, `\"longitude\"`, and `\"geojson\"`) when a\n[geographic projection](projection.html) is applied."
                 }
             },
-            "required": [],
+            "required": [
+                "selection",
+                "test",
+                "type",
+                "value"
+            ],
             "title": "ConditionalPredicateFieldDefClass"
         },
         "OrderFieldDef": {
@@ -3140,7 +3185,9 @@
                     "description": "A constant value in visual domain."
                 }
             },
-            "required": [],
+            "required": [
+                "type"
+            ],
             "title": "TextDefWithCondition",
             "description": "Text of the `text` mark.\nThe tooltip text to show upon mouse hover.\nA FieldDef with Condition<ValueDef>\n{\n   condition: {value: ...},\n   field: ...,\n   ...\n}\nA ValueDef with Condition<ValueDef | FieldDef>\n{\n   condition: {field: ...} | {value: ...},\n   value: ...,\n}"
         },
@@ -3184,7 +3231,12 @@
                     "description": "The encoded field's type of measurement (`\"quantitative\"`, `\"temporal\"`, `\"ordinal\"`, or\n`\"nominal\"`).\nIt can also be a geo type (`\"latitude\"`, `\"longitude\"`, and `\"geojson\"`) when a\n[geographic projection](projection.html) is applied."
                 }
             },
-            "required": [],
+            "required": [
+                "selection",
+                "test",
+                "type",
+                "value"
+            ],
             "title": "ConditionalPredicateTextFieldDefClass"
         },
         "XClass": {
@@ -3246,7 +3298,10 @@
                     "description": "A constant value in visual domain (e.g., `\"red\"` / \"#0099ff\" for color, values between\n`0` to `1` for opacity)."
                 }
             },
-            "required": [],
+            "required": [
+                "type",
+                "value"
+            ],
             "title": "XClass",
             "description": "X coordinates of the marks, or width of horizontal `\"bar\"` and `\"area\"`.\nY coordinates of the marks, or height of vertical `\"bar\"` and `\"area\"`.\nDefinition object for a constant value of an encoding channel."
         },
@@ -3389,7 +3444,10 @@
                     "description": "A constant value in visual domain (e.g., `\"red\"` / \"#0099ff\" for color, values between\n`0` to `1` for opacity)."
                 }
             },
-            "required": [],
+            "required": [
+                "type",
+                "value"
+            ],
             "title": "X2Class",
             "description": "X2 coordinates for ranged  `\"area\"`, `\"bar\"`, `\"rect\"`, and  `\"rule\"`.\nY2 coordinates for ranged  `\"area\"`, `\"bar\"`, `\"rect\"`, and  `\"rule\"`.\nDefinition object for a data field, its type and transformation of an encoding channel.\nDefinition object for a constant value of an encoding channel."
         },
@@ -3502,7 +3560,16 @@
                     "description": "A list of views that should be concatenated and put into a row."
                 }
             },
-            "required": [],
+            "required": [
+                "encoding",
+                "facet",
+                "hconcat",
+                "layer",
+                "mark",
+                "repeat",
+                "spec",
+                "vconcat"
+            ],
             "title": "Spec",
             "description": "Unit spec that can have a composite mark."
         },
@@ -3633,7 +3700,11 @@
                     "description": "A key-value mapping between selection names and definitions."
                 }
             },
-            "required": [],
+            "required": [
+                "encoding",
+                "layer",
+                "mark"
+            ],
             "title": "LayerSpec",
             "description": "Unit spec that can have a composite mark."
         },
@@ -4052,7 +4123,8 @@
                 }
             },
             "required": [
-                "input"
+                "input",
+                "options"
             ],
             "title": "VGBinding"
         },
@@ -4141,7 +4213,16 @@
                     "description": "The data fields to group by. If not specified, a single group containing all data objects\nwill be used."
                 }
             },
-            "required": [],
+            "required": [
+                "aggregate",
+                "bin",
+                "calculate",
+                "field",
+                "filter",
+                "from",
+                "lookup",
+                "timeUnit"
+            ],
             "title": "Transform"
         },
         "AggregatedFieldDef": {
diff --git a/head/schema-swift/test/inputs/schema/required-in-any-of.schema/default/quicktype.swift b/head/schema-swift/test/inputs/schema/required-in-any-of.schema/default/quicktype.swift
new file mode 100644
index 0000000..78309dd
--- /dev/null
+++ b/head/schema-swift/test/inputs/schema/required-in-any-of.schema/default/quicktype.swift
@@ -0,0 +1,134 @@
+// This file was generated from JSON Schema using quicktype, do not modify it directly.
+// To parse the JSON, add this file to your project and do:
+//
+//   let topLevel = try TopLevel(json)
+
+import Foundation
+
+// MARK: - TopLevel
+struct TopLevel: Codable {
+    let anyof: Anyof
+
+    enum CodingKeys: String, CodingKey {
+        case anyof = "anyof"
+    }
+}
+
+// MARK: TopLevel convenience initializers and mutators
+
+extension TopLevel {
+    init(data: Data) throws {
+        self = try newJSONDecoder().decode(TopLevel.self, from: data)
+    }
+
+    init(_ json: String, using encoding: String.Encoding = .utf8) throws {
+        guard let data = json.data(using: encoding) else {
+            throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)
+        }
+        try self.init(data: data)
+    }
+
+    init(fromURL url: URL) throws {
+        try self.init(data: try Data(contentsOf: url))
+    }
+
+    func with(
+        anyof: Anyof? = nil
+    ) -> TopLevel {
+        return TopLevel(
+            anyof: anyof ?? self.anyof
+        )
+    }
+
+    func jsonData() throws -> Data {
+        return try newJSONEncoder().encode(self)
+    }
+
+    func jsonString(encoding: String.Encoding = .utf8) throws -> String? {
+        return String(data: try self.jsonData(), encoding: encoding)
+    }
+}
+
+// MARK: - Anyof
+struct Anyof: Codable {
+    let name: String
+    let size: String?
+
+    enum CodingKeys: String, CodingKey {
+        case name = "name"
+        case size = "size"
+    }
+}
+
+// MARK: Anyof convenience initializers and mutators
+
+extension Anyof {
+    init(data: Data) throws {
+        self = try newJSONDecoder().decode(Anyof.self, from: data)
+    }
+
+    init(_ json: String, using encoding: String.Encoding = .utf8) throws {
+        guard let data = json.data(using: encoding) else {
+            throw NSError(domain: "JSONDecoding", code: 0, userInfo: nil)
+        }
+        try self.init(data: data)
+    }
+
+    init(fromURL url: URL) throws {
+        try self.init(data: try Data(contentsOf: url))
+    }
+
+    func with(
+        name: String? = nil,
+        size: String?? = nil
+    ) -> Anyof {
+        return Anyof(
+            name: name ?? self.name,
+            size: size ?? self.size
+        )
+    }
+
+    func jsonData() throws -> Data {
+        return try newJSONEncoder().encode(self)
+    }
+
+    func jsonString(encoding: String.Encoding = .utf8) throws -> String? {
+        return String(data: try self.jsonData(), encoding: encoding)
+    }
+}
+
+// MARK: - Helper functions for creating encoders and decoders
+
+func newJSONDecoder() -> JSONDecoder {
+    let decoder = JSONDecoder()
+    decoder.dateDecodingStrategy = .custom({ (decoder) -> Date in
+        let container = try decoder.singleValueContainer()
+        let dateStr = try container.decode(String.self)
+
+        let formatter = DateFormatter()
+        formatter.calendar = Calendar(identifier: .iso8601)
+        formatter.locale = Locale(identifier: "en_US_POSIX")
+        formatter.timeZone = TimeZone(secondsFromGMT: 0)
+        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
+        if let date = formatter.date(from: dateStr) {
+            return date
+        }
+        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssXXXXX"
+        if let date = formatter.date(from: dateStr) {
+            return date
+        }
+        throw DecodingError.typeMismatch(Date.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Could not decode date"))
+    })
+    return decoder
+}
+
+func newJSONEncoder() -> JSONEncoder {
+    let encoder = JSONEncoder()
+    let formatter = DateFormatter()
+    formatter.calendar = Calendar(identifier: .iso8601)
+    formatter.locale = Locale(identifier: "en_US_POSIX")
+    formatter.timeZone = TimeZone(secondsFromGMT: 0)
+    formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssXXXXX"
+    encoder.dateEncodingStrategy = .formatted(formatter)
+    return encoder
+}
diff --git a/head/schema-typescript/test/inputs/schema/required-in-any-of.schema/default/TopLevel.ts b/head/schema-typescript/test/inputs/schema/required-in-any-of.schema/default/TopLevel.ts
new file mode 100644
index 0000000..accfb76
--- /dev/null
+++ b/head/schema-typescript/test/inputs/schema/required-in-any-of.schema/default/TopLevel.ts
@@ -0,0 +1,192 @@
+// To parse this data:
+//
+//   import { Convert, TopLevel } from "./TopLevel";
+//
+//   const topLevel = Convert.toTopLevel(json);
+//
+// These functions will throw an error if the JSON doesn't
+// match the expected interface, even if the JSON is valid.
+
+export interface TopLevel {
+    anyof: Anyof;
+}
+
+export interface Anyof {
+    name:  string;
+    size?: string;
+}
+
+// Converts JSON strings to/from your types
+// and asserts the results of JSON.parse at runtime
+export class Convert {
+    public static toTopLevel(json: string): TopLevel {
+        return cast(JSON.parse(json), r("TopLevel"));
+    }
+
+    public static topLevelToJson(value: TopLevel): string {
+        return JSON.stringify(uncast(value, r("TopLevel")), null, 2);
+    }
+}
+
+function invalidValue(typ: any, val: any, key: any, parent: any = ''): never {
+    const prettyTyp = prettyTypeName(typ);
+    const parentText = parent ? ` on ${parent}` : '';
+    const keyText = key ? ` for key "${key}"` : '';
+    throw Error(`Invalid value${keyText}${parentText}. Expected ${prettyTyp} but got ${JSON.stringify(val)}`);
+}
+
+function prettyTypeName(typ: any): string {
+    if (Array.isArray(typ)) {
+        if (typ.length === 2 && typ[0] === undefined) {
+            return `an optional ${prettyTypeName(typ[1])}`;
+        } else {
+            return `one of [${typ.map(a => { return prettyTypeName(a); }).join(", ")}]`;
+        }
+    } else if (typeof typ === "object" && typ.literal !== undefined) {
+        return typ.literal;
+    } else {
+        return typeof typ;
+    }
+}
+
+function jsonToJSProps(typ: any): any {
+    if (typ.jsonToJS === undefined) {
+        const map: any = {};
+        typ.props.forEach((p: any) => map[p.json] = { key: p.js, typ: p.typ });
+        typ.jsonToJS = map;
+    }
+    return typ.jsonToJS;
+}
+
+function jsToJSONProps(typ: any): any {
+    if (typ.jsToJSON === undefined) {
+        const map: any = {};
+        typ.props.forEach((p: any) => map[p.js] = { key: p.json, typ: p.typ });
+        typ.jsToJSON = map;
+    }
+    return typ.jsToJSON;
+}
+
+function transform(val: any, typ: any, getProps: any, key: any = '', parent: any = ''): any {
+    function transformPrimitive(typ: string, val: any): any {
+        if (typeof typ === typeof val) return val;
+        return invalidValue(typ, val, key, parent);
+    }
+
+    function transformUnion(typs: any[], val: any): any {
+        // val must validate against one typ in typs
+        const l = typs.length;
+        for (let i = 0; i < l; i++) {
+            const typ = typs[i];
+            try {
+                return transform(val, typ, getProps);
+            } catch (_) {}
+        }
+        return invalidValue(typs, val, key, parent);
+    }
+
+    function transformEnum(cases: string[], val: any): any {
+        if (cases.indexOf(val) !== -1) return val;
+        return invalidValue(cases.map(a => { return l(a); }), val, key, parent);
+    }
+
+    function transformArray(typ: any, val: any): any {
+        // val must be an array with no invalid elements
+        if (!Array.isArray(val)) return invalidValue(l("array"), val, key, parent);
+        return val.map(el => transform(el, typ, getProps));
+    }
+
+    function transformDate(val: any): any {
+        if (val === null) {
+            return null;
+        }
+        const d = new Date(val);
+        if (isNaN(d.valueOf())) {
+            return invalidValue(l("Date"), val, key, parent);
+        }
+        return d;
+    }
+
+    function transformObject(props: { [k: string]: any }, additional: any, val: any): any {
+        if (val === null || typeof val !== "object" || Array.isArray(val)) {
+            return invalidValue(l(ref || "object"), val, key, parent);
+        }
+        const result: any = {};
+        Object.getOwnPropertyNames(props).forEach(key => {
+            const prop = props[key];
+            const v = Object.prototype.hasOwnProperty.call(val, key) ? val[key] : undefined;
+            result[prop.key] = transform(v, prop.typ, getProps, key, ref);
+        });
+        Object.getOwnPropertyNames(val).forEach(key => {
+            if (!Object.prototype.hasOwnProperty.call(props, key)) {
+                result[key] = transform(val[key], additional, getProps, key, ref);
+            }
+        });
+        return result;
+    }
+
+    if (typ === "any") return val;
+    if (typ === null) {
+        if (val === null) return val;
+        return invalidValue(typ, val, key, parent);
+    }
+    if (typ === false) return invalidValue(typ, val, key, parent);
+    let ref: any = undefined;
+    while (typeof typ === "object" && typ.ref !== undefined) {
+        ref = typ.ref;
+        typ = typeMap[typ.ref];
+    }
+    if (Array.isArray(typ)) return transformEnum(typ, val);
+    if (typeof typ === "object") {
+        return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val)
+            : typ.hasOwnProperty("arrayItems")    ? transformArray(typ.arrayItems, val)
+            : typ.hasOwnProperty("props")         ? transformObject(getProps(typ), typ.additional, val)
+            : invalidValue(typ, val, key, parent);
+    }
+    // Numbers can be parsed by Date but shouldn't be.
+    if (typ === Date && typeof val !== "number") return transformDate(val);
+    return transformPrimitive(typ, val);
+}
+
+function cast<T>(val: any, typ: any): T {
+    return transform(val, typ, jsonToJSProps);
+}
+
+function uncast<T>(val: T, typ: any): any {
+    return transform(val, typ, jsToJSONProps);
+}
+
+function l(typ: any) {
+    return { literal: typ };
+}
+
+function a(typ: any) {
+    return { arrayItems: typ };
+}
+
+function u(...typs: any[]) {
+    return { unionMembers: typs };
+}
+
+function o(props: any[], additional: any) {
+    return { props, additional };
+}
+
+function m(additional: any) {
+    const props: any[] = [];
+    return { props, additional };
+}
+
+function r(name: string) {
+    return { ref: name };
+}
+
+const typeMap: any = {
+    "TopLevel": o([
+        { json: "anyof", js: "anyof", typ: r("Anyof") },
+    ], false),
+    "Anyof": o([
+        { json: "name", js: "name", typ: "" },
+        { json: "size", js: "size", typ: u(undefined, "") },
+    ], false),
+};
diff --git a/head/schema-typescript-zod/test/inputs/schema/required-in-any-of.schema/default/TopLevel.ts b/head/schema-typescript-zod/test/inputs/schema/required-in-any-of.schema/default/TopLevel.ts
new file mode 100644
index 0000000..421270b
--- /dev/null
+++ b/head/schema-typescript-zod/test/inputs/schema/required-in-any-of.schema/default/TopLevel.ts
@@ -0,0 +1,13 @@
+import * as z from "zod";
+
+
+export const AnyofSchema = z.object({
+    "name": z.string(),
+    "size": z.string().optional(),
+});
+export type Anyof = z.infer<typeof AnyofSchema>;
+
+export const TopLevelSchema = z.object({
+    "anyof": AnyofSchema,
+});
+export type TopLevel = z.infer<typeof TopLevelSchema>;
diff --git a/base/schema-typescript-zod/test/inputs/schema/vega-lite.schema/default/TopLevel.ts b/head/schema-typescript-zod/test/inputs/schema/vega-lite.schema/default/TopLevel.ts
index ffd8d12..8aecb11 100644
--- a/base/schema-typescript-zod/test/inputs/schema/vega-lite.schema/default/TopLevel.ts
+++ b/head/schema-typescript-zod/test/inputs/schema/vega-lite.schema/default/TopLevel.ts
@@ -588,40 +588,40 @@ export const SelectionDefTypeSchema = z.enum([
 export type SelectionDefType = z.infer<typeof SelectionDefTypeSchema>;
 
 export type Selection = {
-    "not"?: Selection | string;
-    "and"?: Array<Selection | string>;
-    "or"?: Array<Selection | string>;
+    "not": Selection | string;
+    "and": Array<Selection | string>;
+    "or": Array<Selection | string>;
 };
 export const SelectionSchema: z.ZodType<Selection> = z.lazy(() =>
     z.object({
-        "not": z.union([SelectionSchema, z.string()]).optional(),
-        "and": z.array(z.union([SelectionSchema, z.string()])).optional(),
-        "or": z.array(z.union([SelectionSchema, z.string()])).optional(),
+        "not": z.union([SelectionSchema, z.string()]),
+        "and": z.array(z.union([SelectionSchema, z.string()])),
+        "or": z.array(z.union([SelectionSchema, z.string()])),
     })
 );
 
 export type Predicate = {
-    "not"?: Predicate | string;
-    "and"?: Array<Predicate | string>;
-    "or"?: Array<Predicate | string>;
-    "equal"?: boolean | DateTime | number | string;
-    "field"?: string;
+    "not": Predicate | string;
+    "and": Array<Predicate | string>;
+    "or": Array<Predicate | string>;
+    "equal": boolean | DateTime | number | string;
+    "field": string;
     "timeUnit"?: TimeUnit;
-    "range"?: Array<DateTime | number | null>;
-    "oneOf"?: Array<boolean | DateTime | number | string>;
-    "selection"?: Selection | string;
+    "range": Array<DateTime | number | null>;
+    "oneOf": Array<boolean | DateTime | number | string>;
+    "selection": Selection | string;
 };
 export const PredicateSchema: z.ZodType<Predicate> = z.lazy(() =>
     z.object({
-        "not": z.union([PredicateSchema, z.string()]).optional(),
-        "and": z.array(z.union([PredicateSchema, z.string()])).optional(),
-        "or": z.array(z.union([PredicateSchema, z.string()])).optional(),
-        "equal": z.union([z.boolean(), DateTimeSchema, z.number(), z.string()]).optional(),
-        "field": z.string().optional(),
+        "not": z.union([PredicateSchema, z.string()]),
+        "and": z.array(z.union([PredicateSchema, z.string()])),
+        "or": z.array(z.union([PredicateSchema, z.string()])),
+        "equal": z.union([z.boolean(), DateTimeSchema, z.number(), z.string()]),
+        "field": z.string(),
         "timeUnit": TimeUnitSchema.optional(),
-        "range": z.array(z.union([z.null(), DateTimeSchema, z.number()])).min(2).max(2).optional(),
-        "oneOf": z.array(z.union([z.boolean(), DateTimeSchema, z.number(), z.string()])).optional(),
-        "selection": z.union([SelectionSchema, z.string()]).optional(),
+        "range": z.array(z.union([z.null(), DateTimeSchema, z.number()])).min(2).max(2),
+        "oneOf": z.array(z.union([z.boolean(), DateTimeSchema, z.number(), z.string()])),
+        "selection": z.union([SelectionSchema, z.string()]),
     })
 );
 
@@ -629,42 +629,42 @@ export type Spec = {
     "data"?: Data;
     "description"?: string;
     "height"?: number;
-    "layer"?: Array<LayerSpec>;
+    "layer": Array<LayerSpec>;
     "name"?: string;
     "resolve"?: Resolve;
     "title"?: TitleParams | string;
     "transform"?: Array<Transform>;
     "width"?: number;
-    "encoding"?: Encoding;
-    "mark"?: MarkDef | Mark;
+    "encoding": Encoding;
+    "mark": MarkDef | Mark;
     "projection"?: Projection;
     "selection"?: Record<string, SelectionDef>;
-    "facet"?: FacetMapping;
-    "spec"?: Spec;
-    "repeat"?: Repeat;
-    "vconcat"?: Array<Spec>;
-    "hconcat"?: Array<Spec>;
+    "facet": FacetMapping;
+    "spec": Spec;
+    "repeat": Repeat;
+    "vconcat": Array<Spec>;
+    "hconcat": Array<Spec>;
 };
 export const SpecSchema: z.ZodType<Spec> = z.lazy(() =>
     z.object({
         "data": DataSchema.optional(),
         "description": z.string().optional(),
         "height": z.number().optional(),
-        "layer": z.array(LayerSpecSchema).optional(),
+        "layer": z.array(LayerSpecSchema),
         "name": z.string().optional(),
         "resolve": ResolveSchema.optional(),
         "title": z.union([TitleParamsSchema, z.string()]).optional(),
         "transform": z.array(TransformSchema).optional(),
         "width": z.number().optional(),
-        "encoding": EncodingSchema.optional(),
-        "mark": z.union([MarkDefSchema, MarkSchema]).optional(),
+        "encoding": EncodingSchema,
+        "mark": z.union([MarkDefSchema, MarkSchema]),
         "projection": ProjectionSchema.optional(),
         "selection": z.record(z.string(), SelectionDefSchema).optional(),
-        "facet": FacetMappingSchema.optional(),
-        "spec": SpecSchema.optional(),
-        "repeat": RepeatSchema.optional(),
-        "vconcat": z.array(SpecSchema).optional(),
-        "hconcat": z.array(SpecSchema).optional(),
+        "facet": FacetMappingSchema,
+        "spec": SpecSchema,
+        "repeat": RepeatSchema,
+        "vconcat": z.array(SpecSchema),
+        "hconcat": z.array(SpecSchema),
     })
 );
 
@@ -672,14 +672,14 @@ export type LayerSpec = {
     "data"?: Data;
     "description"?: string;
     "height"?: number;
-    "layer"?: Array<LayerSpec>;
+    "layer": Array<LayerSpec>;
     "name"?: string;
     "resolve"?: Resolve;
     "title"?: TitleParams | string;
     "transform"?: Array<Transform>;
     "width"?: number;
-    "encoding"?: Encoding;
-    "mark"?: MarkDef | Mark;
+    "encoding": Encoding;
+    "mark": MarkDef | Mark;
     "projection"?: Projection;
     "selection"?: Record<string, SelectionDef>;
 };
@@ -688,14 +688,14 @@ export const LayerSpecSchema: z.ZodType<LayerSpec> = z.lazy(() =>
         "data": DataSchema.optional(),
         "description": z.string().optional(),
         "height": z.number().optional(),
-        "layer": z.array(LayerSpecSchema).optional(),
+        "layer": z.array(LayerSpecSchema),
         "name": z.string().optional(),
         "resolve": ResolveSchema.optional(),
         "title": z.union([TitleParamsSchema, z.string()]).optional(),
         "transform": z.array(TransformSchema).optional(),
         "width": z.number().optional(),
-        "encoding": EncodingSchema.optional(),
-        "mark": z.union([MarkDefSchema, MarkSchema]).optional(),
+        "encoding": EncodingSchema,
+        "mark": z.union([MarkDefSchema, MarkSchema]),
         "projection": ProjectionSchema.optional(),
         "selection": z.record(z.string(), SelectionDefSchema).optional(),
     })
@@ -934,7 +934,7 @@ export type ProjectionConfig = z.infer<typeof ProjectionConfigSchema>;
 export const VgSchemeSchema = z.object({
     "count": z.number().optional(),
     "extent": z.array(z.number()).optional(),
-    "scheme": z.string().optional(),
+    "scheme": z.string(),
     "step": z.number().optional(),
 });
 export type VgScheme = z.infer<typeof VgSchemeSchema>;
@@ -987,7 +987,7 @@ export type MultiSelectionConfig = z.infer<typeof MultiSelectionConfigSchema>;
 export const VgBindingSchema = z.object({
     "element": z.string().optional(),
     "input": z.string(),
-    "options": z.array(z.string()).optional(),
+    "options": z.array(z.string()),
     "max": z.number().optional(),
     "min": z.number().optional(),
     "step": z.number().optional(),
@@ -1147,9 +1147,9 @@ export const BinParamsSchema = z.object({
 export type BinParams = z.infer<typeof BinParamsSchema>;
 
 export const ConditionalValueDefSchema = z.object({
-    "test": z.union([PredicateSchema, z.string()]).optional(),
+    "test": z.union([PredicateSchema, z.string()]),
     "value": z.union([z.boolean(), z.number(), z.string()]),
-    "selection": z.union([SelectionSchema, z.string()]).optional(),
+    "selection": z.union([SelectionSchema, z.string()]),
 });
 export type ConditionalValueDef = z.infer<typeof ConditionalValueDefSchema>;
 
@@ -1235,14 +1235,14 @@ export const FieldDefSchema = z.object({
 export type FieldDef = z.infer<typeof FieldDefSchema>;
 
 export const ConditionalPredicateFieldDefClassSchema = z.object({
-    "test": z.union([PredicateSchema, z.string()]).optional(),
-    "value": z.union([z.boolean(), z.number(), z.string()]).optional(),
-    "selection": z.union([SelectionSchema, z.string()]).optional(),
+    "test": z.union([PredicateSchema, z.string()]),
+    "value": z.union([z.boolean(), z.number(), z.string()]),
+    "selection": z.union([SelectionSchema, z.string()]),
     "aggregate": AggregateOpSchema.optional(),
     "bin": z.union([z.boolean(), BinParamsSchema]).optional(),
     "field": z.union([RepeatRefSchema, z.string()]).optional(),
     "timeUnit": TimeUnitSchema.optional(),
-    "type": TypeSchema.optional(),
+    "type": TypeSchema,
 });
 export type ConditionalPredicateFieldDefClass = z.infer<typeof ConditionalPredicateFieldDefClassSchema>;
 
@@ -1257,15 +1257,15 @@ export const OrderFieldDefSchema = z.object({
 export type OrderFieldDef = z.infer<typeof OrderFieldDefSchema>;
 
 export const ConditionalPredicateTextFieldDefClassSchema = z.object({
-    "test": z.union([PredicateSchema, z.string()]).optional(),
-    "value": z.union([z.boolean(), z.number(), z.string()]).optional(),
-    "selection": z.union([SelectionSchema, z.string()]).optional(),
+    "test": z.union([PredicateSchema, z.string()]),
+    "value": z.union([z.boolean(), z.number(), z.string()]),
+    "selection": z.union([SelectionSchema, z.string()]),
     "aggregate": AggregateOpSchema.optional(),
     "bin": z.union([z.boolean(), BinParamsSchema]).optional(),
     "field": z.union([RepeatRefSchema, z.string()]).optional(),
     "format": z.string().optional(),
     "timeUnit": TimeUnitSchema.optional(),
-    "type": TypeSchema.optional(),
+    "type": TypeSchema,
 });
 export type ConditionalPredicateTextFieldDefClass = z.infer<typeof ConditionalPredicateTextFieldDefClassSchema>;
 
@@ -1300,8 +1300,8 @@ export const X2ClassSchema = z.object({
     "bin": z.union([z.boolean(), BinParamsSchema]).optional(),
     "field": z.union([RepeatRefSchema, z.string()]).optional(),
     "timeUnit": TimeUnitSchema.optional(),
-    "type": TypeSchema.optional(),
-    "value": z.union([z.boolean(), z.number(), z.string()]).optional(),
+    "type": TypeSchema,
+    "value": z.union([z.boolean(), z.number(), z.string()]),
 });
 export type X2Class = z.infer<typeof X2ClassSchema>;
 
@@ -1449,9 +1449,9 @@ export type SingleSelectionConfig = z.infer<typeof SingleSelectionConfigSchema>;
 
 export const DataSchema = z.object({
     "format": DataFormatSchema.optional(),
-    "url": z.string().optional(),
-    "values": z.union([z.array(z.union([z.boolean(), z.number(), z.record(z.string(), z.any()), z.string()])), z.record(z.string(), z.any()), z.string()]).optional(),
-    "name": z.string().optional(),
+    "url": z.string(),
+    "values": z.union([z.array(z.union([z.boolean(), z.number(), z.record(z.string(), z.any()), z.string()])), z.record(z.string(), z.any()), z.string()]),
+    "name": z.string(),
 });
 export type Data = z.infer<typeof DataSchema>;
 
@@ -1491,7 +1491,7 @@ export const DefWithConditionSchema = z.object({
     "condition": z.union([z.array(ConditionalValueDefSchema), ConditionalPredicateFieldDefClassSchema]).optional(),
     "field": z.union([RepeatRefSchema, z.string()]).optional(),
     "timeUnit": TimeUnitSchema.optional(),
-    "type": TypeSchema.optional(),
+    "type": TypeSchema,
     "value": z.union([z.boolean(), z.number(), z.string()]).optional(),
 });
 export type DefWithCondition = z.infer<typeof DefWithConditionSchema>;
@@ -1503,7 +1503,7 @@ export const TextDefWithConditionSchema = z.object({
     "field": z.union([RepeatRefSchema, z.string()]).optional(),
     "format": z.string().optional(),
     "timeUnit": TimeUnitSchema.optional(),
-    "type": TypeSchema.optional(),
+    "type": TypeSchema,
     "value": z.union([z.boolean(), z.number(), z.string()]).optional(),
 });
 export type TextDefWithCondition = z.infer<typeof TextDefWithConditionSchema>;
@@ -1517,8 +1517,8 @@ export const XClassSchema = z.object({
     "sort": z.union([z.null(), SortFieldSchema, SortEnumSchema]).optional(),
     "stack": z.union([z.null(), StackOffsetSchema]).optional(),
     "timeUnit": TimeUnitSchema.optional(),
-    "type": TypeSchema.optional(),
-    "value": z.union([z.boolean(), z.number(), z.string()]).optional(),
+    "type": TypeSchema,
+    "value": z.union([z.boolean(), z.number(), z.string()]),
 });
 export type XClass = z.infer<typeof XClassSchema>;
 
@@ -1550,9 +1550,9 @@ export const SelectionConfigSchema = z.object({
 export type SelectionConfig = z.infer<typeof SelectionConfigSchema>;
 
 export const ConditionalPredicateMarkPropFieldDefClassSchema = z.object({
-    "test": z.union([PredicateSchema, z.string()]).optional(),
-    "value": z.union([z.boolean(), z.number(), z.string()]).optional(),
-    "selection": z.union([SelectionSchema, z.string()]).optional(),
+    "test": z.union([PredicateSchema, z.string()]),
+    "value": z.union([z.boolean(), z.number(), z.string()]),
+    "selection": z.union([SelectionSchema, z.string()]),
     "aggregate": AggregateOpSchema.optional(),
     "bin": z.union([z.boolean(), BinParamsSchema]).optional(),
     "field": z.union([RepeatRefSchema, z.string()]).optional(),
@@ -1560,21 +1560,21 @@ export const ConditionalPredicateMarkPropFieldDefClassSchema = z.object({
     "scale": ScaleSchema.optional(),
     "sort": z.union([z.null(), SortFieldSchema, SortEnumSchema]).optional(),
     "timeUnit": TimeUnitSchema.optional(),
-    "type": TypeSchema.optional(),
+    "type": TypeSchema,
 });
 export type ConditionalPredicateMarkPropFieldDefClass = z.infer<typeof ConditionalPredicateMarkPropFieldDefClassSchema>;
 
 export const TransformSchema = z.object({
-    "filter": z.union([PredicateSchema, z.string()]).optional(),
+    "filter": z.union([PredicateSchema, z.string()]),
     "as": z.union([z.array(z.string()), z.string()]).optional(),
-    "calculate": z.string().optional(),
+    "calculate": z.string(),
     "default": z.string().optional(),
-    "from": LookupDataSchema.optional(),
-    "lookup": z.string().optional(),
-    "bin": z.union([z.boolean(), BinParamsSchema]).optional(),
-    "field": z.string().optional(),
-    "timeUnit": TimeUnitSchema.optional(),
-    "aggregate": z.array(AggregatedFieldDefSchema).optional(),
+    "from": LookupDataSchema,
+    "lookup": z.string(),
+    "bin": z.union([z.boolean(), BinParamsSchema]),
+    "field": z.string(),
+    "timeUnit": TimeUnitSchema,
+    "aggregate": z.array(AggregatedFieldDefSchema),
     "groupby": z.array(z.string()).optional(),
 });
 export type Transform = z.infer<typeof TransformSchema>;
@@ -1629,7 +1629,7 @@ export const MarkPropDefWithConditionSchema = z.object({
     "scale": ScaleSchema.optional(),
     "sort": z.union([z.null(), SortFieldSchema, SortEnumSchema]).optional(),
     "timeUnit": TimeUnitSchema.optional(),
-    "type": TypeSchema.optional(),
+    "type": TypeSchema,
     "value": z.union([z.boolean(), z.number(), z.string()]).optional(),
 });
 export type MarkPropDefWithCondition = z.infer<typeof MarkPropDefWithConditionSchema>;
@@ -1677,9 +1677,9 @@ export const TopLevelSchema = z.object({
     "config": ConfigSchema.optional(),
     "data": DataSchema.optional(),
     "description": z.string().optional(),
-    "encoding": EncodingWithFacetSchema.optional(),
+    "encoding": EncodingWithFacetSchema,
     "height": z.number().optional(),
-    "mark": z.union([MarkDefSchema, MarkSchema]).optional(),
+    "mark": z.union([MarkDefSchema, MarkSchema]),
     "name": z.string().optional(),
     "padding": z.union([PaddingClassSchema, z.number()]).optional(),
     "projection": ProjectionSchema.optional(),
@@ -1687,12 +1687,12 @@ export const TopLevelSchema = z.object({
     "title": z.union([TitleParamsSchema, z.string()]).optional(),
     "transform": z.array(TransformSchema).optional(),
     "width": z.number().optional(),
-    "layer": z.array(LayerSpecSchema).optional(),
+    "layer": z.array(LayerSpecSchema),
     "resolve": ResolveSchema.optional(),
-    "facet": FacetMappingSchema.optional(),
-    "spec": SpecSchema.optional(),
-    "repeat": RepeatSchema.optional(),
-    "vconcat": z.array(SpecSchema).optional(),
-    "hconcat": z.array(SpecSchema).optional(),
+    "facet": FacetMappingSchema,
+    "spec": SpecSchema,
+    "repeat": RepeatSchema,
+    "vconcat": z.array(SpecSchema),
+    "hconcat": z.array(SpecSchema),
 });
 export type TopLevel = z.infer<typeof TopLevelSchema>;
