Christian Sakai
Christian Sakai

Reputation: 979

Incompatible flow-type for generic higher order function

Flow says that the type that is being returned by voidnullify below is incompatible. I think I am missing something?

import faker from 'faker'

type P =
  | string
  | number
  | boolean

function voidnullify(func: () => P): ?P {
  const random: number = faker.random.number({
    min: 1, 
    max: 10
  })

  const result = func()

  if (random <= 7) return result
  else if (random <= 9) return null
  else return undefined
}

function someBoolean() {
  return true
}

function someString() {
  return "hello"
}

function someNumber() {
  return 1
}

let maybeNum: ?number
let maybeStr: ?string
let maybeBool: ?boolean

maybeNum = voidnullify(someNumber) 
maybeStr = voidnullify(someString) 
maybeBool = voidnullify(someBoolean) 

Upvotes: 0

Views: 381

Answers (1)

Lewis Chung
Lewis Chung

Reputation: 2327

I think what you're doing the way you're trying to do it is just unsupported. I'm not sure if it should work, but as you're trying to just guard the input types (it looks like?), the proper way to do that in Flow is with bounded polymorphism + generic parameters:

type P =
  | string
  | number
  | boolean

function voidnullify<A: P>(func: () => A): ?A {
  const random: number = faker.random.number({
    min: 1, 
    max: 10
  })
  ...

Upvotes: 1

Related Questions