如何验证深度嵌套的对象结构

我已经定义了具有嵌套属性的对象。我想创建一个验证器函数,它将检查另一个对象是否与我定义的对象具有相同的结构和值类型!


是对象的定义:


const OBJECT_SCHEMA = {

  name: String,

  data: [{

    isSelected: Boolean,

    mId: String,

    mSummary: String,

    mMarkets: Array,

    mBdd: String,

    mReplaceDict: Object,

    omId: String,

    omnSummary: String,

    omnMarkets: Array,

    omnBdd: String,

    omnReplaceDict: {

      id: String,

      text: String,

    },

  }],

  metadata: {

    emails: Array,

    description: String,

  },

};

这是我用于验证的功能。目前它仅适用于一个嵌套级别!我希望它使用许多嵌套级别进行验证。


function validateObjectStructure(schema, obj) {

  let valid = true;

  firstLevel: for(const k in schema) {

    if(schema[k].constructor === Array) { // if prop is of type array

      let i;

      for(i = 0; i < schema[k].length; i++) {

        for(const kk in schema[k][i]) {

          if(!obj[k][i].hasOwnProperty(kk) || obj[k][i][kk].constructor !== schema[k][i][kk]) {

            valid = false;

            break firstLevel;

          }

        }

      }

    }

    else if(schema[k].constructor === Object) { // if prop is of type object

      for(const kk in schema[k]) {

        if(!obj[k].hasOwnProperty(kk) || obj[k][kk].constructor !== schema[k][kk]) {

          valid = false;

          break firstLevel;

        }

      }

    }

    else { // if prop is simple type

      if(!obj.hasOwnProperty(k) || obj[k].constructor !== schema[k]) {

        valid = false;

        break;

      }

    }

  }

  return valid;

}


千万里不及你
浏览 195回答 2
2回答

交互式爱情

您是否需要使用 的嵌套级别obj?如果是,你可以做这样的事情而不是最后一行:Object.values(obj).reduce((accValid, value) => {&nbsp; if (typeof value === 'object') {&nbsp; &nbsp; return accValid && validateObjectStructure(schema, value);&nbsp; }&nbsp; return accValid;}, valid);return valid;

心有法竹

这是一个可能的实现:function validate(obj, schema, path = '') {&nbsp; &nbsp; let ok = true;&nbsp; &nbsp; if (!obj)&nbsp; &nbsp; &nbsp; &nbsp; ok = obj === schema;&nbsp; &nbsp; else if (typeof schema === 'function')&nbsp; &nbsp; &nbsp; &nbsp; ok = obj.constructor === schema;&nbsp; &nbsp; else if (typeof obj !== 'object')&nbsp; &nbsp; &nbsp; &nbsp; ok = obj === schema;&nbsp; &nbsp; else if (Array.isArray(schema))&nbsp; &nbsp; &nbsp; &nbsp; ok = Array.isArray(obj) && obj.every((x, k) => validate(x, schema[0], path + '[' + k + ']'));&nbsp; &nbsp; else {&nbsp; &nbsp; &nbsp; &nbsp; let ko = Object.keys(obj);&nbsp; &nbsp; &nbsp; &nbsp; let ks = Object.keys(schema);&nbsp; &nbsp; &nbsp; &nbsp; ok = ko.length === ks.length && ks.every(k => validate(obj[k], schema[k], path + '.' + k));&nbsp; &nbsp; }&nbsp; &nbsp; if (!ok)&nbsp; &nbsp; &nbsp; &nbsp; throw new Error('FAILED ' + path);&nbsp; &nbsp; return true;}// example:const OBJECT_SCHEMA = {&nbsp; &nbsp; name: String,&nbsp; &nbsp; data: [{&nbsp; &nbsp; &nbsp; &nbsp; isSelected: Boolean,&nbsp; &nbsp; &nbsp; &nbsp; mId: String,&nbsp; &nbsp; &nbsp; &nbsp; omnReplaceDict: {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; id: String,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; text: {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; deepObj: {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; deepProp: [Number]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; }],};const obj = {&nbsp; &nbsp; name: "foo",&nbsp; &nbsp; data: [{&nbsp; &nbsp; &nbsp; &nbsp; isSelected: true,&nbsp; &nbsp; &nbsp; &nbsp; mId: "bar",&nbsp; &nbsp; &nbsp; &nbsp; omnReplaceDict: {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; id: "foo",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; text: {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; deepObj: {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; deepProp: [1, 2, "???", 3]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; }]};validate(obj, OBJECT_SCHEMA)注意:虽然这个自制的类型检查器看起来工作正常,但它非常有限(例如如何表达“字符串数字对的数组”或“null 或某个对象”?),所以它可能是使用一个选项真正的,就像打字稿一样。有关可能的实现,请参见此处。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript