如何在流中输入一个采用函数生成数据的高阶函数?

How can I type in flow a high order function that takes a function to generate data?

我想使用泛型键入一个模拟查询的函数。为了最大程度地灵活使用要使用的数据类型(并避免 returning 相同的引用数据),此函数采用另一个函数来生成 return 的数据。因为这个函数可以return任何数据类型,所以我不想限制它为任何特定类型,但我也不想使用any

我认为这可以通过泛型实现,但我尝试正确键入它的所有尝试都失败了。到目前为止,这是我尝试过的:

//@flow
import { useState, useEffect } from 'react'

export const makeUseQuery = <T>(generateData: () => T) => () => {
  const [data, setData] = useState()
  const [isLoading, setIsLoading] = useState(true)
  useEffect(() => {
    const id = setTimeout(() => {
      setData(generateData())
      setIsLoading(false)
    }, 2500)
    return () => {
      clearTimeout(id)
    }
  }, [])
  return {
    data,
    isLoading,
    error: null,
  }
}

我从流程中得到的错误是我不能让泛型从范围中逃脱,但我不确定我还能如何保证这种类型的安全。

也许是这样的?

import { useState, useEffect } from 'react'

type UseQueryResult<Response> = $ReadOnly<{|
  data: Response | void,
  isLoading: boolean,
  error: null,
|}>;

export const makeUseQuery = <Response>(
  generateData: () => Response
): (() => UseQueryResult<Response>) => 
(): UseQueryResult<Response> => {
  const [data, setData] = useState()
  const [isLoading, setIsLoading] = useState(true)
  useEffect(() => {
    const id = setTimeout(() => {
      setData(generateData())
      setIsLoading(false)
    }, 2500)
    return () => {
      clearTimeout(id)
    }
  }, [])
  return {
    data,
    isLoading,
    error: null,
  }
}

(try)