isValidField(
    fieldName,
    documentSubset,
    collectionSpecSubset,
    strictness,
    errorMessages,
    verbose,
  ) {
    /** @type StructuredFieldSpecification */
    const field = collectionSpecSubset[fieldName];
    let result = true;

    if (
      field.mandatory &&
      !has(field, "defaultValue") &&
      _.isNil(documentSubset[fieldName])
    ) {
      manageErrorMessage(
        field.path,
        errorMessages,
        "The field is mandatory.",
        verbose,
      );
      return false;
    }

    if (!_.isNil(documentSubset[fieldName])) {
      let nestedStrictness = false,
        fieldValues;

      if (field.multivalued.value) {
        if (!Array.isArray(documentSubset[fieldName])) {
          manageErrorMessage(
            field.path,
            errorMessages,
            "The field must be multivalued, unary value provided.",
            verbose,
          );
          return false;
        }

        if (
          has(field.multivalued, "minCount") &&
          documentSubset[fieldName].length < field.multivalued.minCount
        ) {
          manageErrorMessage(
            field.path,
            errorMessages,
            `Not enough elements. Minimum count is set to ${field.multivalued.minCount}.`,
            verbose,
          );
          return false;
        }

        if (
          has(field.multivalued, "maxCount") &&
          documentSubset[fieldName].length > field.multivalued.maxCount
        ) {
          manageErrorMessage(
            field.path,
            errorMessages,
            `Too many elements. Maximum count is set to ${field.multivalued.maxCount}.`,
            verbose,
          );
          return false;
        }

        fieldValues = documentSubset[fieldName];
      } else {
        if (Array.isArray(documentSubset[fieldName])) {
          manageErrorMessage(
            field.path,
            errorMessages,
            "The field is not a multivalued field; Multiple values provided.",
            verbose,
          );
          return false;
        }

        fieldValues = [documentSubset[fieldName]];
      }

      if (this.types[field.type].allowChildren) {
        nestedStrictness = this.types[field.type].getStrictness(
          field.typeOptions,
          strictness,
        );
      }

      for (const val of fieldValues) {
        const fieldErrors = [];

        if (
          !this.types[field.type].validate(field.typeOptions, val, fieldErrors)
        ) {
          if (fieldErrors.length === 0) {
            // We still want to trigger an error, even if no message is provided
            manageErrorMessage(
              field.path,
              errorMessages,
              "An error has occurred during validation.",
              verbose,
            );
          } else {
            fieldErrors.forEach((message) =>
              manageErrorMessage(field.path, errorMessages, message, verbose),
            );
          }
          return false;
        }

        if (this.types[field.type].allowChildren && field.children) {
          try {
            if (
              !this.recurseFieldValidation(
                val,
                field.children,
                nestedStrictness,
                errorMessages,
                verbose,
              )
            ) {
              result = false;
            }
          } catch (error) {
            if (error.message === "strictness") {
              manageErrorMessage(
                field.path,
                errorMessages,
                `The field is set to "strict"; cannot add unspecified sub-field "${error.details.field}".`,
                verbose,
              );
            } else if (verbose) {
              manageErrorMessage(
                field.path,
                errorMessages,
                error.message,
                verbose,
              );
            } else {
              throw error;
            }

            result = false;
          }
        }
      }
    }
    return result;
  }
@param {string} fieldName
@param {*} documentSubset
@param {StructuredFieldSpecification} collectionSpecSubset
@param {boolean} strictness
@param {string[]} errorMessages
@param {boolean} verbose
@returns {boolean}