Why does Flow infer type in an unexpected way?

Viewed 41

I have this sort of code:

export type MapType = "AdventureMap" | "GuidebookMap";

type MapContext = {|
  mapType: MapType
|}

const context: MapContext = { mapType: "GuidebookMap" };

const { mapType } = context;

// A: no error in this line
if (mapType === "ABC-INVALID") {}

function fun(value: MapType) {
  // B: error in this line
  if (value === "123-INVALID") {}
}

// C: error in this line
fun(mapType);

When compiling this in Flow, line B and C fails, because it infers that type of mapType is MapType | string. Why does it do that? Is there a way to change it?

I expect it to fail on lines A and B, as it does on Typescript.


I can do this:

const mapType: MapType = context.mapType;

but it somewhat beats the purpose as I'm forced to specify types explicitly. Also, you can not "extract" multiple properties in one statement and I have to specify types for each. Is there a setting in the config to make it work more like Typescript?

1 Answers

You can do this when you are destructuring, you can specify types like that. /* @flow */

export type MapType = "AdventureMap" | "GuidebookMap";

type MapContext = {|
  mapType: MapType
|}

const context: MapContext = { mapType: "GuidebookMap" };

const { mapType }:{
    mapType: MapType
} = context;

// A: no error in this line
if (mapType === "ABC-INVALID") {}

function fun(value: MapType) {
  // B: error in this line
  if (value === "123-INVALID") {}
}

// C: error in this line
fun(mapType);
Related