带参数和ReturnType的extends Function的正确用法是什么

时间:2019-03-21 20:25:24

标签: typescript redux reselect

我正在尝试创建自己的备注功能以进行重新选择。我必须重新定义ParametersReturnType才能接受extends Function(错误?)。 myMemoize的签名正确,但是内部函数签名未编译。

import { createSelectorCreator } from "reselect";

type Parameters<T extends Function> = T extends (...args: infer P) => any ? P : never;
type ReturnType<T extends Function> = T extends (...args: any[]) => infer R ? R : any;

function myMemoize<F extends Function>(func: F): F {
  // ...
  return function(...args: Parameters<F>): ReturnType<F> {
    //...
    return func.apply(null, args)
  }
}

export const createMyMemoizeSelector = createSelectorCreator(myMemoize)

错误:

error TS2322: Type '(...args: Parameters<F>) => ReturnType<F>' is not assignable to type 'F'

2 个答案:

答案 0 :(得分:1)

问题在于您的新函数与原始函数的类型实际上不同。原始属性可能具有其他属性,您无法将其转发给return函数。

您可以跳过返回类型,而ParametersReturnType(两者都已定义,因此不必重新定义它们)对于完整类型的版本实际上不是必需的:

function myMemoize<P extends any[], R>(func: (...a:P)=> R): (...a:P)=> R {
  // ...
  return function(...args: P): R {
    //...
    return func.apply(null, args)
  }
}

虽然不确定该如何与createSelectorCreator交互。

答案 1 :(得分:0)

  

Type '(...args: Parameters<F>) => ReturnType<F>' is not assignable to type 'F'

从根本上说...args包含任意数量的参数,而F可能需要非常具体的计数。

修复

您的用例不需要Prameters / ReturnType,因为(func: F): F涵盖了外部类型安全,并且您不需要内部类型安全。这是更简单的方法:

function myMemoize<F extends Function>(func: F): F {
  // ...
  return function(...args: any[]): any {
    //...
    return func.apply(null, args)
  }
}