【问题标题】:Define generic function type and apply to function assignment定义泛型函数类型并应用于函数赋值
【发布时间】:2022-01-02 11:37:13
【问题描述】:

我可以像这样定义和使用通用函数:

const fetchData = <T>(): T[] => {
  const arr: T[] = []
  // if stuff push to arr
  return arr
}

const emptyStringArray = fetchData<string>();

但是,在我的实际场景中,我有很多参数,并且想将类型和函数分配分开。

我尝试过这样写:

type IFetchData = <T>() => T[]

const fetchData2: IFetchData = () => {
  const arr: T[] = []
  // if stuff push to arr
  return arr
}

const emptyStringArray = fetchData2<string>();

但是,现在函数定义无法将 T 识别为可用类型。

找不到名称“T”。

我已经尝试了很多不同的配置来放置&lt;T&gt;,但似乎没有任何效果 - 有什么想法吗?

Demo in TS Playground


相关问题

【问题讨论】:

    标签: typescript typescript-generics


    【解决方案1】:

    IFetchData 正在为您输入返回值,因此它应该可以从fetchData2 函数返回值中省略泛型。以下是否有效?

    type IFetchData = <T>() => T[]
    const fetchData2: IFetchData = () => {
      return [];
    }
    

    【讨论】:

    • 关闭,但理想情况下,我可以在定义中保留泛型。它在尝试创建一个小示例时得到了简化,但我实际上是在创建一个初始数组并将对象推送到它 - 更新示例
    • 嗯,如果您需要访问 fetchData2 内部的泛型,该方法似乎与您的初始方法相似(没有 IFetchData: const fetchData2 = &lt;T&gt;() =&gt; { const arr: T[] = []; return arr;}
    【解决方案2】:

    你可以试试吗?

    type IFetchData = <T>() => T[]
    const fetchData2: IFetchData = <T>() => {
      return [];
    }
    

    【讨论】:

      【解决方案3】:

      首先,这个函数:

      const fetchData = <T,>(): T[] => {
          const arr: T[] = []
          arr.push(2) // error
          arr.push('str') // error
      
          return arr
      }
      
      

      很难用。

      由于您的所有参数都与T 无关,因此TS 将不允许您将push 的任何值传递给arr。当然也可以使用类型断言as,但是很不安全:

      const fetchData = <T,>(): T[] => {
          const arr: T[] = []
          arr.push('str' as any as T) // error
      
          return arr
      }
      
      const emptyStringArray = fetchData<number>(); // number[]
      emptyStringArray[0].toExponential() // runtime error
      

      相关question/answermy article

      答案很简单:在这种情况下,如果没有变通方法,就不可能将T 与函数定义分开。

      这里有最简单的方法:

      const fetchData = <T,>() => {
        const arr: T[] = []
        return arr
      }
      

      然而,如果你想在fetchData 中改变你的数组,这个函数签名是没有用的。这个函数不允许对arr 做任何事情。您所能做的就是返回 arr 而不进行任何更改。

      为了改变这个列表,你需要创建高阶函数并在调用fetchData时提供显式的泛型参数:

      type FetchData = <T>() => T[]
      const fetchData: FetchData = () => []
      
      const higherOrder = <T,>(elem: T) => {
        const arr = fetchData<T>();
        arr.push(elem)
      
        return arr
      }
      
      
      
      const test = higherOrder('str'); // ok, string[]
      const test2 = higherOrder(42); // ok, number[]
      
      

      Playground

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-03
        • 1970-01-01
        • 2020-12-27
        • 2020-07-04
        • 2013-11-26
        • 2018-12-08
        相关资源
        最近更新 更多