2

I need to check that a user specified predicate always returns a boolean value. Sample code looks like this:

let isMostlyBoolean = function (aPredicate) {

return ( typeof aPredicate(undefined) === 'boolean' &&
    typeof aPredicate(null) === 'boolean' &&
    typeof aPredicate(false) === 'boolean' &&
    typeof aPredicate(Number.NaN) === 'boolean' &&
    typeof aPredicate(256) === 'boolean' &&
    typeof aPredicate("text") === 'boolean' &&
    typeof aPredicate('s') === 'boolean' &&
    typeof aPredicate(Math.sqrt) === 'boolean' &&
    typeof aPredicate(Object) === 'boolean' &&
    typeof aPredicate(['x', 'y', 'z']) === 'boolean'
);

}

which works. Is there a more neat and/or efficient way of aPredicate check-up? Here we scan all possible data types one by one.

As stated in _.isFunction(a) vs. typeof a === 'function'? javascript discussion the typeof should be the way to go. Any idea how to do that in more fancy and readable way?

Edit: Note that the test above is a kind of fuzzy logic. Function name was changed accordingly. See @georg comments and more below.

Given the test code:

let prediLess = (x) => x<2;
let predicate = (x) => x || (x<2);

console.log("isMostlyBoolean(prediLess): ", isMostlyBoolean(prediLess));
console.log("isMostlyBoolean(predicate): ", isMostlyBoolean(predicate));

console.log("\nprediLess(undefined): ", prediLess(undefined));
console.log("prediLess(1): ", prediLess(1));
console.log("prediLess(Object): ", prediLess(Object));

console.log("\npredicate(undefined): ", predicate(undefined));
console.log("predicate(1): ", predicate(1));
console.log("predicate(Object): ", predicate(Object));

the console output is:

returnsBoolean(prediLess):  true
returnsBoolean(predicate):  false

prediLess(undefined):  false
prediLess(1):  true
prediLess(Object):  false

predicate(undefined):  false
predicate(1):  1
predicate(Object):  function Object() { [native code] }
dev7
  • 91
  • 2
  • 6
  • 3
    I'm not sure what your function is supposed to check. Javascript is loosely-typed, there's no guarantee whatsoever that given an argument of type A, the function always returns type B. So it's perfectly possible for `aPredicate` to return `boolean` for "256" and a number for say "257". – georg Feb 19 '18 at 13:04
  • 1
    ...agreed. if you want typesafety you should have a look at typescript... – Jonas Wilms Feb 19 '18 at 13:13
  • @georg It is intended for efficiency. Given a function like `newGenerator(oldGenerator, aPredicate)` with a `aPredicate` misconfigured we do not call `oldGenerator`, a new function just returns `undefined`. – dev7 Feb 19 '18 at 13:22

1 Answers1

5
 [undefined, null, NaN, 0, 1, "", "a", [], [1], {}].every(el => typeof aPredicate(el) === "boolean");

Just store all possible values in an array and iterate over it and check that every value fits.

Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151