亲爱的TypeScript-3-Gurus,
有人可以帮助我定义执行以下操作的泛型类型GuruMagic<T>
吗?
T
是一个返回函数的函数,例如这个:
fetchUser(id: Id) => (dispatch: Dispatch) => Promise<boolean>
然后,泛型类型应使用返回的函数的ReturnType
替换 fetchUser
中的ReturnType
。像这样:
type dispatchedAction = GuruMagic<typeof fetchUser>;
// so that dispatchedAction === (id: Id) => Promise<boolean>
我知道我可以两次申请ReturnType
来获得Promise<boolean>
,但是我不知道如何用这种返回类型连接原始参数(可能是多个)。使用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
动机
Typesafe Redux-Thunk
。当我connect
一个react
组件时,如果我能做到这一点,那就太好了:
import { fetchUser } from './myActions';
interface IPropsOfMyComponent {
fetchUser: GuruMagic<typeof fetchUser>;
}
// ... MyComponent Definition ...
connect<{}, IPropsOfMyComponent, {}>(null, { fetchUser })(MyComponent)
答案 0 :(得分:2)
是的,您可以使用conditional types并通过对tuple types in rest and spread expressions的支持在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;
因此,您将函数FF
的参数列表推断为A
,并将函数FF
的返回类型的返回类型推断为R
,然后返回从A
到R
的参数列表的新函数。可以吗?
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
是的!
我不确定100%会在实践中使用此类型函数...它忽略了中间函数的参数类型这一事实让我感到担忧。给定类型为GuruMagic<T>
的函数,如果您尝试实际实现类型为T
的函数,除非您以某种方式提供缺少的参数,否则您将遇到问题。但是也许您甚至都没有实现给定GuruMagic<T>
的{{1}}。无论如何,那是你的事,而不是我的事。
无论如何,希望能有所帮助。祝你好运!