【问题标题】:How to declare a generic function that returns a function (react hook) with same parameters but different return type from its parameter如何声明一个泛型函数,该函数返回具有相同参数但返回类型与其参数不同的函数(反应挂钩)
【发布时间】:2021-07-03 16:53:22
【问题描述】:

在 TypeScript 中,如何声明一个遵循上述规则的函数 f

f 是一个函数:

  • 将另一个函数callback作为参数;和
  • 返回不同的函数hook
  • 其中 hook 接受与 callback 相同的参数,但有一个 不同的返回类型

强调“不同的返回类型”...

我的具体目标是键入我实现的 React Hook,但我的问题与 hook 本身无关。相反,它与类型声明有关。

我非常接近解决方案,但仍然缺少一块...基于this answer from a different but similar question,我能够为函数添加类型提示,正确覆盖参数,但这种方法在于返回类型:

这是我的代码:

import { useRef } from 'react';

export default function useTimeoutDebounce<F extends Function>(callback: F, ms: number): F {
    const timeout = useRef<number>();
    const timeoutDebounce = (...args: any[]) => {
        if (typeof window !== 'undefined') {
            window.clearTimeout(timeout.current);
            timeout.current = window.setTimeout(() => {
                callback(...args)
            }, ms);
        }
    };

    // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
    return <any>timeoutDebounce;
}

有了该代码,我就可以像这样使用它了:

请注意,TypeScript 已成功检查参数的类型!太好了!

但是,看看另一个例子,(这是我想要改变的行为)

注意钩子的返回类型是boolean,这是一个谎言。正如你在钩子声明中看到的,它是一个 void 函数。

我在考虑长远。对函数的返回类型进行类型提示最终会在维护代码时出现问题。

P.s.:我查看了 Parameters 实用程序类型,但我无法使其适用于我的情况,因为它不适用于 Function

来自documentation

type T7 = Parameters<Function>;
Type 'Function' does not satisfy the constraint '(...args: any) => any'.
  Type 'Function' provides no match for the signature '(...args: any): any'.

【问题讨论】:

    标签: typescript react-hooks typescript-generics


    【解决方案1】:

    我猜解决方案看起来像这样(我将它写成我认为是针对您的问题的最小可重现示例)。

    在下面的案例中,您可以看到 aToC 函数是从 aToB 函数构造的,它最终具有相同的参数签名但返回值不同。有一个 typescript playground 表示它可以编译,您可以将鼠标悬停在 aToC 上以检查类型并从那里进行实验。

    type A = "A";
    type B = "B";
    type C = "C";
    
    function retypeFunction<Params extends any[]>(fun: (...params:Params) =>B) : (...params:Params) =>C {
        return (...params:Params) => "C"
    }
    
    function aToB(a:A):B{
       return "B"; 
    }
    
    const aToC = retypeFunction(aToB);
    

    【讨论】:

    • 这个问题解决了我的问题,谢谢!这里要补充一点,fun 的返回类型也可以是泛型的:function retypeFunction&lt;Params extends any[], T&gt;(fun: (...params:Params) =&gt; T) : (...params:Params) =&gt;C { ... 这样,我们就不需要事先知道它的返回类型了。
    • 对,我想保持简单,但应该澄清一般情况。很高兴它有帮助。
    猜你喜欢
    • 2018-12-24
    • 2019-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-25
    相关资源
    最近更新 更多