flow types with constant strings, and dependent types

Instead of declaring FOO as a const, declare it as a disjoint union with just one branch:

type FOO = "FOO"

Then your code can be updated like this:

const example = (foo : string) : {| type: FOO, foo: string |} => {
  return {type: "FOO", foo: foo}
}

If you use any value besides the exact string literal "FOO" where a FOO is required, then it is a compile error.

If you would prefer to keep your constant, then you'll need to name the type differently, as they would collide. So you could do:

const FOO = "FOO"
type FooType = "FOO";

const example = (foo : string) : {| type: FooType, foo: string |} => {
  return {type: FOO, foo: foo}
}

Unfortunately, I can't see a way to avoid duplicating the string literal, because type disjoint union definition syntax only permits literals and types, not variables even if they are constants.


Found a workaround for the issue, Instead of using flow type inference we can specify the literal type

export default const FOO:'FOO' = 'FOO'

then in the function you can use as

const example = (foo : string) : {| type: typeof FOO, foo: string |} => {
return {type: FOO, foo: foo}
}

Because when you declare the constant type is inferred to be string also I believe flow doesn't support setting type definitions from variables or constants.