提取接口中其他道具的通用类型

extracting the generic type of other props in interface

我怎样才能实现这样的目标?

interface Props {
   result: <type of function with a lot of generic>
   data: <type of one of the generics in the function above>
}

我发现了一个听起来很相似的问题 ,但我是个新手,不确定这是否适用于我的情况。

背景:

我正在使用 react-query,并希望制作一个包装器组件,该组件采用反应查询结果对象和一个组件,然后根据查询状态(isLoading、isSuccess)显示微调器或给定组件等),无论查询响应数据类型是什么。

import React from 'react'
import {useQuery} from 'react-query'

interface WrapperProps {
   result: <type of react query result>;
   render: (data: <type of query data>) => React.ReactNode;
}

const Wrapper: React.FC<WrapperProps> = ({result, render}) => {
  if (result.isLoading) {
     return <div>spinner</div>
  }

  if (result.isSuccess) {
    return render(result.data)
  }

  return <div>otherwise</div>
}


const App: React.FC = () => { 
  const responseString = useQuery(
    ['string']
    async () => Promise.resolve("string")
  )

  const responseNumber = useQuery(
    ['number']
    async () => Promise.resolve(3)
  )

  return (
    <div>
    <Wrapper 
      result={responseString}
      render={(data) => (<div>successfully loaded string {data}</div>)} // <= want the data to be type string
    />
    <Wrapper 
      result={responseInt}
      render={(data) => (<div>successfully loaded int {data}</div>)} // <= want the data to be type number
    />
    </div>

  )
}

*1 useQuery 的类型类似于 this

你很接近。您需要稍微更新 Wrapper 组件。

首先,你需要摆脱FC。相反,您需要添加额外的通用类型来推断查询结果。

考虑这个例子:

import React from 'react'

import { useQuery, UseQueryResult } from 'react-query'

interface WrapperProps<T> {
  result: UseQueryResult<T, unknown>
  render: (data: T) => JSX.Element;
}

const Wrapper = <T,>({ result, render }: WrapperProps<T>) => {
  if (result.isLoading) {
    return <div>spinner</div>
  }

  if (result.isSuccess) {
    return render(result.data)
  }

  return <div>otherwise</div>
}


const App: React.FC = () => {
  const responseString = useQuery(
    ['string'],
    async () => Promise.resolve("string")
  )

  const responseNumber = useQuery(
    ['number'],
    async () => Promise.resolve(3)
  )

  return (
    <div>
      <Wrapper
        result={responseString}
        render={(data /** string */) => (<div>successfully loaded string {data}</div>)}
      />
      <Wrapper
        result={responseNumber}
        render={(data /** number */) => (<div>successfully loaded int {data}</div>)}
      />
    </div>

  )
}

Playground

请记住,无法推断具有额外泛型和 FC 显式类型的组件 props。

请注意 TS,因为 2.9 支持 React 组件的显式泛型