[英]Generic TypeScript Type for functions returning functions that replaces the ReturnType with the ReturnType of the returned function
Dear TypeScript-3-Gurus out there, 亲爱的TypeScript-3-Gurus,
can someone help my define a generic type GuruMagic<T>
that does the following? 有人可以帮助我定义以下类型的通用类型
GuruMagic<T>
吗?
T
is a function returning a function, eg this: T
是一个返回函数的函数,例如:
fetchUser(id: Id) => (dispatch: Dispatch) => Promise<boolean>
The generic type should then replace the ReturnType
of fetchUser
with the ReturnType
of the returned function. 然后,泛型类型应将
ReturnType
的fetchUser
替换为返回函数的ReturnType
。 Like this: 像这样:
type dispatchedAction = GuruMagic<typeof fetchUser>;
// so that dispatchedAction === (id: Id) => Promise<boolean>
I know that I can apply ReturnType
two times to get Promise<boolean>
, but I don't know how to concat the original parameters (possibly multiple) with this return type. 我知道我可以两次应用
ReturnType
来获取Promise<boolean>
,但是我不知道如何用这种返回类型连接原始参数(可能是多个)。 Is this even possible with TypeScript (3.x)? 使用TypeScript(3.x)甚至可能吗?
Other examples for clarity 为清楚起见,其他示例
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
Motivation 动机
Typesafe Redux-Thunk
. Typesafe
Redux-Thunk
。 When I connect
a react
component it would be great if I could just do this: 当我
connect
一个react
组件时,如果我能做到这一点就太好了:
import { fetchUser } from './myActions';
interface IPropsOfMyComponent {
fetchUser: GuruMagic<typeof fetchUser>;
}
// ... MyComponent Definition ...
connect<{}, IPropsOfMyComponent, {}>(null, { fetchUser })(MyComponent)
Yes, you can do this with conditional types and the generic argument-list manipulation powers introduced in TypeScript 3.0 via support for tuple types in rest and spread expressions . 是的,您可以使用条件类型和TypeScript 3.0中引入的通用参数列表操作能力来实现这一点,方法是支持rest和spread表达式中的元组类型 。 Here's one way to do it:
这是一种实现方法:
type GuruMagic<FF extends (...args: any[]) => (...args: any[]) => any> =
FF extends (...args: infer A) => (...args: infer _) => infer R ? (...args: A) => R
: never;
So you infer the argument list for the function FF
as A
, and the return type of the return type of the function FF
as R
, and then return a new function from an argument list of A
to R
. 所以,你推断该函数的参数列表
FF
为A
,和函数的返回类型的返回类型FF
为R
然后从参数列表返回一个新的功能, A
到R
Does it work? 它行得通吗?
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
Yes it does! 是的,它确实!
I'm not 100% sure how you will use this type function in practice... the fact that it ignores the type of the arguments of the intermediate function worries me. 我不是100%地确定您将如何在实践中使用此类型函数……事实上,它忽略了中间函数的参数类型,这一点令我感到担忧。 If you try to actually implement a function of type
GuruMagic<T>
given a function of type T
you will have a problem unless you supply the missing arguments somehow. 如果尝试给定类型
T
的函数实际实现类型为GuruMagic<T>
的函数,除非您以某种方式提供缺少的参数,否则您将遇到问题。 But maybe you're not even implementing a GuruMagic<T>
given a T
. 但是也许您甚至没有实现给定
T
的GuruMagic<T>
。 Anyway, that's your business, not mine. 无论如何,这是您的事,而不是我的事。
Anyway, hope that helps. 无论如何,希望能有所帮助。 Good luck!
祝好运!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.