简体   繁体   English

通用函数的 Typescript ReturnType

[英]Typescript ReturnType of generic function

The new ReturnType in TypeScript 2.8 is a really useful feature that lets you extract the return type of a particular function. TypeScript 2.8 中的新ReturnType是一个非常有用的功能,可让您提取特定函数的返回类型。

function foo(e: number): number {
    return e;
}

type fooReturn = ReturnType<typeof foo>; // number

However, I'm having trouble using it in the context of generic functions.但是,我在通用函数的上下文中使用它时遇到了麻烦。

function foo<T>(e: T): T {
    return e;
}

type fooReturn = ReturnType<typeof foo>; // type fooReturn = {}

type fooReturn = ReturnType<typeof foo<number>>; // syntax error

type fooReturn = ReturnType<(typeof foo)<number>>; // syntax error

Is there a way extract the return type that a generic function would have given particular type parameters?有没有办法提取泛型函数给定特定类型参数的返回类型?

If you want to get some special generic type, You can use a fake function to wrap it.如果你想得到一些特殊的泛型类型,你可以使用一个假函数来包装它。

const wrapperFoo = () => foo<number>()
type Return = ReturnType<typeof wrapperFoo>

More complex demo更复杂的演示

function getList<T>(): {
  list: T[],
  add: (v: T) => void,
  remove: (v: T) => void,
  // ...blahblah
}
const wrapperGetList = () => getList<number>()
type List = ReturnType<typeof wrapperGetList>
// List = {list: number[], add: (v: number) => void, remove: (v: number) => void, ...blahblah}

This is my currently working solution for extracting un-exported internal types of imported libraries (like knex):这是我目前用于提取未导出的内部类型的导入库(如 knex)的工作解决方案:

// foo is an imported function that I have no control over
function foo<T>(e: T): InternalType<T> {
    return e;
}

class Wrapper<T> {
  // wrapped has no explicit return type so we can infer it
  wrapped(e: T) {
    return foo<T>(e)
  }
}

type FooInternalType<T> = ReturnType<Wrapper<T>['wrapped']>
type Y = FooInternalType<number>
// Y === InternalType<number>

I found a good and easy way to achieve this if you can change the function definition.如果您可以更改函数定义,我找到了一种很好且简单的方法来实现这一点。 In my case, I needed to use the typescript type Parameters with a generic function, precisely I was trying Parameters<typeof foo<T>> and effectively it doesn't work.就我而言,我需要将 typescript 类型Parameters与泛型函数一起使用,正是我在尝试Parameters<typeof foo<T>>并且实际上它不起作用。 So the best way to achieve this is changing the function definition by an interface function definition , this also will work with the typescript type ReturnType .所以最好的方式实现这一目标是通过一个接口函数定义改变功能的定义,这也将与打字稿类型工作ReturnType

Here an example following the case described by the OP:以下是 OP 描述的案例的示例:

function foo<T>(e: T): T {
   return e;
}

type fooReturn = ReturnType<typeof foo<number>>; // Damn! it throws error

// BUT if you try defining your function as an interface like this:

interface foo<T>{
   (e: T): T
}

type fooReturn = ReturnType<foo<number>> //it's number, It works!!!
type fooParams = Parameters<foo<string>> //it also works!! it is [string]

//and you can use the interface in this way
const myfoo: foo<number> = (asd: number) => {
    return asd;
};

myfoo(7);
const wrapperFoo = (process.env.NODE_ENV === 'development' ? foo<number>() : undefined)!
type Return = typeof wrapperFoo

Instead of development for NODE_ENV I would even use test or some random string like typescript_helper (just as long as TypeScript doesn't throw an error) so that it never executes since it won't be used in runtime.代替NODE_ENVdevelopment ,我什NODE_ENV会使用test或一些随机字符串,比如typescript_helper (只要 TypeScript 不抛出错误),这样它就永远不会执行,因为它不会在运行时使用。

I found a solution.我找到了解决方案。 You decide if it fits your needs :)您决定它是否适合您的需求:)

Declare your function args and return type using a interface使用接口声明函数参数和返回类型

interface Foo<T, V> {
  (t: T, v: V): [T, V]
}

Implement your function this way using Parameters and ReturnType使用ParametersReturnType这种方式实现您的函数

function foo<T, V>(...[t, v]: Parameters<Foo<T, V>>): ReturnType<Foo<T, V>> {
  return [t, v]; // [T, V]
}

Call your function normally, or get return type using ReturnType正常调用您的函数,或使用ReturnType获取返回类型

foo(1, 'a') // [number, string]
type Test = ReturnType<Foo<number, number>> // [number, number]

TypeScript compiler does not see typeof foo as generic type. TypeScript 编译器不会将typeof foo视为泛型类型。 I'd say it's a bug in the compiler.我会说这是编译器中的一个错误。

However, TypeScript has callable interfaces which can be generic without any problems, so if you introduce a callable interface compatible with the signature of your function, you can implement your own equivalent of ReturnType like this:但是,TypeScript 具有可调用接口,这些接口可以是通用的,没有任何问题,因此如果您引入与函数签名兼容的可调用接口,则可以像这样实现自己的ReturnType等价物:

function foo<T>(x: T): T {
  return x;
}


interface Callable<R> {
  (...args: any[]): R;
}

type GenericReturnType<R, X> = X extends Callable<R> ? R : never;

type N = GenericReturnType<number, typeof foo>; // number

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 TypeScript - 通用函数的 ReturnType 不起作用 - TypeScript - ReturnType of a generic function not working 我可以将 function(并获取其 ReturnType)传递给通用 TypeScript 类型吗? - Can I pass a function (and get its ReturnType) to a generic TypeScript type? 函数返回函数的通用TypeScript类型,该函数将ReturnType替换为返回函数的ReturnType - Generic TypeScript Type for functions returning functions that replaces the ReturnType with the ReturnType of the returned function 打字稿:重载函数的返回类型 - Typescript: ReturnType of overloaded function Typescript function 返回类型 - Typescript function returntype 通用 class 方法的 Typescript ReturnType 问题 - Typescript ReturnType problem for generic class method Typescript:通用参数/ReturnType 和字符串枚举有问题 - Typescript: Problem with generic Parameter/ReturnType and string Enums 将typescript ReturnType与keyof和通用类型的迭代键一起使用 - Using typescript ReturnType with keyof and iterated keys of generic type TypeScript: ReturnType -&gt; 如何设置 function 返回的 function 的返回类型 - TypeScript: ReturnType -> How to set the return type of function returned by a function TypeScript:在使用接口的对象中传递嵌套函数的 ReturnType - TypeScript: pass the ReturnType of a nested function in an object that uses Interface
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM