函数返回函数的通用 TypeScript 类型,用返回函数的 ReturnType 替换 ReturnType [英] Generic TypeScript Type for functions returning functions that replaces the ReturnType with the ReturnType of the returned function

查看:65
本文介绍了函数返回函数的通用 TypeScript 类型,用返回函数的 ReturnType 替换 ReturnType的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

亲爱的 TypeScript-3-Gurus,

有人可以帮助我定义一个通用类型 GuruMagic 来执行以下操作吗?

can someone help my define a generic type GuruMagic<T> that does the following?

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

T is a function returning a function, e.g. this:

fetchUser(id: Id) => (dispatch: Dispatch) => Promise<boolean>

泛型类型应该替换fetchUserReturnType与返回函数的ReturnType.像这样:

The generic type should then replace the ReturnTypeof fetchUserwith the ReturnTypeof the returned function. Like this:

type dispatchedAction = GuruMagic<typeof fetchUser>;
// so that dispatchedAction === (id: Id) => Promise<boolean>

我知道我可以应用 ReturnType 两次来获得 Promise,但我不知道如何将原始参数(可能是多个)与这种返回类型.这甚至可以用 TypeScript (3.x) 实现吗?

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. Is this even possible with 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 组件时,如果我能做到这一点就好了:

Typesafe Redux-Thunk. When I connect a react component it would be great if I could just do this:

import { fetchUser } from './myActions';

interface IPropsOfMyComponent {
  fetchUser: GuruMagic<typeof fetchUser>;
}

// ... MyComponent Definition ...

connect<{}, IPropsOfMyComponent, {}>(null, { fetchUser })(MyComponent)

推荐答案

是的,您可以使用 条件类型 以及 TypeScript 3.0 中通过支持 rest 和 spread 表达式中的元组类型.这是一种方法:

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. 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;

所以你推断函数FF的参数列表为A,函数FF的返回类型的返回类型为R,然后从 A 的参数列表返回一个新函数给 R.有用吗?

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. 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

是的!

我不是 100% 确定你将如何在实践中使用这个类型函数......它忽略了中间函数的参数类型这一事实让我担心.如果您尝试实际实现 GuruMagic<T> 类型的函数给定 T 类型的函数,除非您以某种方式提供缺少的参数,否则您将遇到问题.但也许您甚至没有在给定 T 的情况下实现 GuruMagic.不管怎样,那是你的事,不是我的.

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. 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. But maybe you're not even implementing a GuruMagic<T> given a T. Anyway, that's your business, not mine.

无论如何,希望有所帮助.祝你好运!

Anyway, hope that helps. Good luck!

这篇关于函数返回函数的通用 TypeScript 类型,用返回函数的 ReturnType 替换 ReturnType的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆