Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
346 views
in Technique[技术] by (71.8m points)

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

I want to type using generics a function that simulates a query. To give the most flexibility to the type of data to be used (and to avoid returning same referenced data) this function takes another function to generate the data to return. Because this function can return any data type, I don't want to restrict it to any specific type, but I don't want to use any either.

I thought this could be something achievable with generics, but all my attempts to type it properly fail. Here is what I tried so far:

//@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,
  }
}

The error I get from flow is that I can not let the generic escape from the scope, but I am not sure how else can I keep this type safe.

question from:https://stackoverflow.com/questions/66050852/how-can-i-type-in-flow-a-high-order-function-that-takes-a-function-to-generate-d

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Maybe something like this?

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)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...