vedantroy / typecheck.macro

A easy (and fast) typescript validation library/macro. Automatically generate validation functions for Typescript types.
MIT License
413 stars 7 forks source link

Make code more concise for boolean operations #3

Open vedantroy opened 4 years ago

vedantroy commented 4 years ago

Rather than generating (for example) !(a === undefined), we should generate a !== undefined. This could be done by having a variable in the State interface that says whether the parent is negating the current expression. If they are, we can just inline the negation and signal the parent (maybe by adding another type to Validator) that we negated the expression.

decadef20 commented 4 years ago

Is this issue fixed? If not, I want to have a try.

vedantroy commented 4 years ago

Sure, give it a shot! Let me know if you have questions about the code.

decadef20 commented 4 years ago

I scanned the tests and did not find code like !(a=== undefined) in createValidator().toString(). What kinds of types can generate !(a === undefined)? Can you provide a sample code? Thanks.

vedantroy commented 4 years ago

If you run the tests and look in the "tests-compiled" folder you should see the generated code. An example of a test where we have the above inefficiency is in tests_compiled/exec/array.js.

Note: I think fixing this issue might be really hard because the current code generation strategy is pretty easy in the sense that we can wrap any child expression in parenthesis and then slap a ! at the beginning to negate it.

decadef20 commented 4 years ago

I think I know the problem. new the code is

  const validator = p0 => !!p0 && p0.constructor === Array && (p1 => {
    for (const p2 of p1) {
      if (!(!!p2 && p2.constructor === Array && (p4 => {
        for (const p5 of p4) {
          if (!(typeof p5 === "number")) return false;
        }

        return true;
      })(p2) || typeof p2 === "number")) return false;
    }

    return true;
  })(p0);

It will be

  const validator = p0 => !!p0 && p0.constructor === Array && (p1 => {
    for (const p2 of p1) {
      if ((!!p2 && p2.constructor !== Array && (p4 => {
        for (const p5 of p4) {
          if ((typeof p5 !== "number")) return false;
        }

        return true;
      })(p2) || typeof p2 !== "number")) return false;
    }

    return true;
  })(p0);
vedantroy commented 4 years ago

Yeah, if you could do that. It would be amazing!!