简体   繁体   中英

How can I do a write run-time type-check expression using Flow type?

Suppose I have two types defined in Flow:

type A = {
  x : string; 
};

type B = {
  y : string; 
};

Now I have a function f like this:

const f = (o : A | B) : string => {
  if (o isa A) { // Not real code
    return o.x;
  }
  return o.y;
};

How do I implement o isa A ?

I want to create an expression that checks an object against a Flow type-definition at run-time.

The compiled code might look like this:

const f = o => {
  if (typeof(o.x) !== 'undefined') {
    return o.x;
  }
  return o.y;
};

There are two primary issues here.

  1. Nothing says a B -typed object can't have a x property too, just like A , and same for the inverse.
  2. Flow isn't quite smart enough to differentiate object types this way.

For the first point, to be clear, your existing definition is fine with

var o: B = {
  x: 45,
  y: "string",
};

because { y: string } means "an object where y is a string ", not "an object with only a y that is a string ."

To get the behavior you are expecting, you'd need to use Flow's Exact Object Syntax as

type A = {|
  x : string; 
|};

type B = {|
  y : string; 
|};

Now to the second point, the easiest approach is

const f = (o : A | B) : string => {
  if (typeof o.x !== "undefined") {
    return o.x;
  }
  if (typeof o.y !== "undefined") {
    return o.y;
  }
  throw new Error("Unreachable code path");
};

to make it clear to Flow that the two cases where the properties exist are the only two cases where a string can be returned.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM