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

时间:2019-11-01 10:08:19

标签: javascript

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

这是对象的定义:

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;
}

2 个答案:

答案 0 :(得分:0)

您是否需要使用obj的嵌套级别?如果是,则可以执行以下操作而不是最后一行:

Object.values(obj).reduce((accValid, value) => {
  if (typeof value === 'object') {
    return accValid && validateObjectStructure(schema, value);
  }
  return accValid;
}, valid);

return valid;

答案 1 :(得分:0)

这是可能的实现方式:

Information:Groovyc: While compiling tests of hes-service:java.lang.NoClassDefFoundError: org/codehaus/groovy/ast/MethodCallTransformation needed for org.codehaus.groovy.macro.transform.MacroTransformation
    at org.jetbrains.jps.incremental.groovy.JointCompilationClassLoader._defineClass(JointCompilationClassLoader.java:41)
    at com.intellij.util.lang.UrlClassLoader.defineClass(UrlClassLoader.java:291)
    at com.intellij.util.lang.UrlClassLoader.findClass(UrlClassLoader.java:245)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
    at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:702)
    at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:812)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
    at groovy.lang.GroovyClassLoader.loadClass(GroovyClassLoader.java:702)
    at org.codehaus.groovy.transform.ASTTransformationVisitor.addPhaseOperationsForGlobalTransforms(ASTTransformationVisitor.java:326)
    at org.codehaus.groovy.transform.ASTTransformationVisitor.doAddGlobalTransforms(ASTTransformationVisitor.java:307)
    at org.codehaus.groovy.transform.ASTTransformationVisitor.addGlobalTransforms(ASTTransformationVisitor.java:210)
    at org.codehaus.groovy.transform.ASTTransformationVisitor.addPhaseOperations(ASTTransformationVisitor.java:174)
    at org.codehaus.groovy.control.CompilationUnit.<init>(CompilationUnit.java:228)
    at org.jetbrains.groovy.compiler.rt.DependentGroovycRunner$2.<init>(DependentGroovycRunner.java:355)
    at org.jetbrains.groovy.compiler.rt.DependentGroovycRunner.createCompilationUnit(DependentGroovycRunner.java:355)
    at org.jetbrains.groovy.compiler.rt.DependentGroovycRunner.runGroovyc(DependentGroovycRunner.java:104)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.jetbrains.groovy.compiler.rt.GroovycRunner.intMain2(GroovycRunner.java:90)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.jetbrains.jps.incremental.groovy.InProcessGroovyc.runGroovycInThisProcess(InProcessGroovyc.java:160)
    at org.jetbrains.jps.incremental.groovy.InProcessGroovyc.lambda$runGroovyc$0(InProcessGroovyc.java:89)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NoClassDefFoundError: org/codehaus/groovy/ast/MethodCallTransformation
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:642)
    at com.intellij.util.lang.UrlClassLoader._defineClass(UrlClassLoader.java:295)
    at org.jetbrains.jps.incremental.groovy.JointCompilationClassLoader._defineClass(JointCompilationClassLoader.java:38)
    ... 31 more
Caused by: java.lang.ClassNotFoundException: org.codehaus.groovy.ast.MethodCallTransformation
    at com.intellij.util.lang.UrlClassLoader.findClass(UrlClassLoader.java:241)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 36 more

Information:javac 1.8.0_201 was used to compile java sources

Information:2019/11/1 18:55 - Compilation completed with 1 error and 92 warnings in 18 s 526 ms

Error:Groovyc: Internal groovyc error: code 1

注意:尽管这个自制的类型检查器似乎可以正常工作,但是它非常有限(例如,如何表达“字符串-数字对数组”或“ null或某些对象”?),因此它可能是一个选择雇用一个真正的人,例如Typescript。有关可能的实现,请参见here