Reactjs 泛型类型返回函数的脚本类型,该函数使用返回函数的返回类型替换返回类型

Reactjs 泛型类型返回函数的脚本类型,该函数使用返回函数的返回类型替换返回类型,reactjs,typescript,redux,typescript-typings,redux-thunk,Reactjs,Typescript,Redux,Typescript Typings,Redux Thunk,亲爱的TypeScript-3-Gurus, 有人能帮我定义一个通用类型GuruMagic,它执行以下操作吗 T是一个返回函数的函数,例如: fetchUser(id: Id) => (dispatch: Dispatch) => Promise<boolean> 我知道我可以应用两次ReturnType来获得Promise,但我不知道如何使用此返回类型来连接原始参数(可能是多个)。这在TypeScript(3.x)中是否可能实现 为清晰起见,其他示例 const f1

亲爱的TypeScript-3-Gurus,

有人能帮我定义一个通用类型
GuruMagic
,它执行以下操作吗

T
是一个返回函数的函数,例如:

fetchUser(id: Id) => (dispatch: Dispatch) => Promise<boolean>
我知道我可以应用两次
ReturnType
来获得
Promise
,但我不知道如何使用此返回类型来连接原始参数(可能是多个)。这在TypeScript(3.x)中是否可能实现

为清晰起见,其他示例

const f1 = (a: number, b: string) => () => a;
type guruF1 = GuruMagic<typeof f1>; // (a: number, b: string) => number

const f2 = () => (name: string) => (otherName: string) => name + otherName;
type guruF2 = GuruMagic<typeof f2>; // () => (otherName: string) => string
是的,通过对的支持,您可以使用TypeScript 3.0中引入的和通用参数列表操纵功能来实现这一点。这里有一种方法:

type GuruMagic<FF extends (...args: any[]) => (...args: any[]) => any> =
  FF extends (...args: infer A) => (...args: infer _) => infer R ? (...args: A) => R 
  : never;
是的,是的

我不是100%确定你将如何在实践中使用这种类型的函数。。。它忽略了中间函数的参数类型这一事实让我担心。如果您试图实际实现
GuruMagic
类型的函数,并且给定了
T
类型的函数,那么您将遇到问题,除非您以某种方式提供缺少的参数。但是,如果给定
T
,您可能甚至没有实现
GuruMagic
。不管怎样,那是你的事,不是我的事

不管怎样,希望这有帮助。祝你好运

是的,通过对的支持,您可以使用TypeScript 3.0中引入的通用参数列表操作功能来实现这一点。这里有一种方法:

type GuruMagic<FF extends (...args: any[]) => (...args: any[]) => any> =
  FF extends (...args: infer A) => (...args: infer _) => infer R ? (...args: A) => R 
  : never;
是的,是的

我不是100%确定你将如何在实践中使用这种类型的函数。。。它忽略了中间函数的参数类型这一事实让我担心。如果您试图实际实现
GuruMagic
类型的函数,并且给定了
T
类型的函数,那么您将遇到问题,除非您以某种方式提供缺少的参数。但是,如果给定
T
,您可能甚至没有实现
GuruMagic
。不管怎样,那是你的事,不是我的事


不管怎样,希望这有帮助。祝你好运

谢谢你的回答!很好用!我只会用这个来重做重击动作。中间参数被我忽略,但在调度操作时由redux本身使用。当您将一个对象作为
mapDispatchToProps
参数传递时(如我的动机代码块的最后一行所示),redux基本上将其转换为
{fetchUser:(…args)=>dispatch(fetchUser(…args))}
。因此,您的
GuruMagic
类型可以让我更轻松地推断出该类型的结果类型,从而生成我的组件道具。再次感谢!:)注:我可能会调整你的定义,只允许
ThunkActions
。完美答案!不过我很好奇,有没有办法修改它来处理函数对象?@PeterKottas你说的“函数对象”是什么意思?所需的输入和输出类型是什么?可能你只是想用一个。如果您的问题更复杂,或者您需要更多的帮助,您可能需要自己提出问题。@jcalz与这里提到的示例完全相同,我只需要object,其中值是函数。我想在那个对象上使用这个GuruMagic,而不是单个函数。其思想是,它将为您提供该对象的类型,从而减少该对象中所有函数的复制粘贴代码。(您也可能忘记映射一个函数)实际上这可能会起作用(afk)
键入GuruObjectMagic={
[P in keyof T]?:GuruMagic;
}
感谢您给出了这个惊人的答案!很好用!我只会用这个来重做重击动作。中间参数被我忽略,但在调度操作时由redux本身使用。当您将一个对象作为
mapDispatchToProps
参数传递时(如我的动机代码块的最后一行所示),redux基本上将其转换为
{fetchUser:(…args)=>dispatch(fetchUser(…args))}
。因此,您的
GuruMagic
类型可以让我更轻松地推断出该类型的结果类型,从而生成我的组件道具。再次感谢!:)注:我可能会调整你的定义,只允许
ThunkActions
。完美答案!不过我很好奇,有没有办法修改它来处理函数对象?@PeterKottas你说的“函数对象”是什么意思?所需的输入和输出类型是什么?可能你只是想用一个。如果您的问题更复杂,或者您需要更多的帮助,您可能需要自己提出问题。@jcalz与这里提到的示例完全相同,我只需要object,其中值是函数。我想在那个对象上使用这个GuruMagic,而不是单个函数。其思想是,它将为您提供该对象的类型,从而减少该对象中所有函数的复制粘贴代码。(您也可能忘记映射一个函数)实际上这可能会起作用(afk)
键入GuruObjectMagic={
[P in keyof T]?:GuruMagic;
}
type GuruMagic<FF extends (...args: any[]) => (...args: any[]) => any> =
  FF extends (...args: infer A) => (...args: infer _) => infer R ? (...args: A) => R 
  : never;
declare function fetchUser(id: Id): (dispatch: Dispatch) => Promise<boolean>
type dispatchedAction = GuruMagic<typeof fetchUser>;
// (id: Id) => Promise<boolean>

const f1 = (a: number, b: string) => () => a;
type guruF1 = GuruMagic<typeof f1>; 
// (a: number, b: string) => number

const f2 = () => (name: string) => (otherName: string) => name + otherName;
type guruF2 = GuruMagic<typeof f2>; 
// () => (otherName: string) => string