异步回调的打字稿定义

Typescript definition for an async callback

我有一个用于获取数据的 React 挂钩:

const useData = (fetchingFn) => {
  const [data, setData] = useState(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState(null)

  // ... handle loading data by calling `fechingFn()`, etc

  return {
    data,
    loading,
    error
  }
}

我正在尝试向其中添加一些 typescript 调味汁,但有点吃力,因为我对 typescript 有点陌生。如果有人能给我指出正确的方向,我愿意给你买一块饼干。

我已经为钩子的 return 值添加了类型定义:

type UseDataReturnType = {
  error: Error | null
  loading: boolean
  data: any | null
}

const useData = (fetchingFn: () => Promise<any>): UseDataReturnType  => {
...

你会注意到我目前有两种 any 类型。

我认为这个:fetchingFn: () => Promise<any> 可能没问题,因为我不想限制可以使用钩子的数据类型,理论上,任何东西都应该没问题。

我 运行 遇到的麻烦是,当使用钩子时,所有类型数据都会丢失,因此当我稍后尝试访问数据时,它被视为 any类型。

这里有一个 hook 的使用示例:

const fetchLoggedInUser = async (): Promise<User> => {
  return db.get('users','bob'
}

const MyView = (): JSX.Element => {
  const { loading, data, error } = useData(fetchLoggedInUserProfile)

  // the data should be of type `User|null` here but instead, it is `any`
}

您可以使用泛型强类型化调用的 return 类型。为此,您必须传入 promise 将解析为的类型,并且挂钩使用该类型并传递以保存类型信息。

这就是您传递类型信息的方式。

// pass along the type info to the hook.

//** Usage when calling the hook **//
// The type is passed along in <>
const { loading, data, error } = useData<User>(fetchLoggedInUserProfile);

//** Hook Definition **//
// TData is the generic type. It can be named anything
// The promise is expected to return type that is passed in which is TData in the // definition, but User when the hook is used
// And lastly you pass in the captured type along to the return type, as the 
// return type contains some additional meta info along with the original return type.
const useData = <TData>(fetchingFn: () => Promise<TData>): UseDataReturnType<TData>  => {
}

//** Type consuming the generic **//
type UseDataReturnType<TData> = {
  error: Error | null
  loading: boolean
  data: TData | null
}