Can I create custom dynamic type tests?

97 Views Asked by At

I'm trying to figure something out using Facebook's Flow type checker.

Say I have the following code, everything works:

function isGreaterThan5(x : string | number) {

    if (typeof x === 'string') {
        return parseInt(x) > 5;
    }

    return x > 5;
}

Because flow's dynamic type tests recognize the typeof check.

However -- if I refactor this code slightly and break out the typeof check, it fails:

function isString(y) {
  return typeof y === 'string';
}

function isGreaterThan5(x : string | number) {

    if (isString(x)) {
        return parseInt(x) > 5;
    }

    return x > 5;
}

Is it possible to somehow mark my isString function as a pure-function which validates for a particular type? Like

function isString(y) { /* typecheck string */
  return typeof y === 'string';
}

or something?

Another reason this seems necessary is for instanceof checks, which can give unexpected results when type checking objects from a different frame: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof#instanceof_and_multiple_context_(e.g._frames_or_windows)

As such it's sometimes necessary to abstract these checks out into helper functions, which given the above, Flow doesn't seem to respect...

Thanks in advance for any help!

1

There are 1 best solutions below

0
On

Officially Flow does not support custom predicates, however the syntax for custom predicates (experimental and undocumented) is:

// I'm using a comment containing the type here because otherwise babel throws
function isString(y)/*: boolean %checks */ {
  return typeof y === 'string'
}

function isGreaterThan5(x: string | number) {
  if (isString(x)) {
    return parseInt(x) > 5
  }
  return x > 5
}