Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript返回泛型函数的类型_Typescript_Generics - Fatal编程技术网

Typescript返回泛型函数的类型

Typescript返回泛型函数的类型,typescript,generics,Typescript,Generics,中的新ReturnType是一个非常有用的功能,它允许您提取特定函数的返回类型 function foo(e: number): number { return e; } type fooReturn = ReturnType<typeof foo>; // number 函数foo(e:number):number{ 返回e; } 类型fooreurn=ReturnType;//数 但是,我在泛型函数的上下文中使用它时遇到了问题 function foo<T&g

中的新
ReturnType
是一个非常有用的功能,它允许您提取特定函数的返回类型

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

type fooReturn = ReturnType<typeof foo>; // number
函数foo(e:number):number{ 返回e; } 类型fooreurn=ReturnType;//数 但是,我在泛型函数的上下文中使用它时遇到了问题

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
函数foo(e:T):T{ 返回e; } 类型fooreurn=ReturnType;//类型fooreurn={} 类型fooreurn=ReturnType;//语法错误 类型fooreurn=ReturnType;//语法错误
是否有一种方法可以提取泛型函数给定特定类型参数时的返回类型?

TypeScript编译器不会将
typeof foo
视为泛型类型。我认为这是编译器中的一个bug

但是,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
函数foo(x:T):T{ 返回x; } 接口可调用{ (…args:any[]):R; } 类型GenericReturnType=X扩展可调用?R:从来没有; 类型N=GenericReturnType;//数
如果你想得到一些特殊的泛型类型,你可以使用一个假函数来包装它

const wrapperFoo = () => foo<number>()
type Return = ReturnType<typeof wrapperFoo>
constwrapperfoo=()=>foo()
返回类型=返回类型
更复杂的演示

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}
函数getList():{
列表:T[],
加:(v:T)=>无效,
移除:(v:T)=>无效,
//…布拉布拉
}
const wrapperGetList=()=>getList()
类型列表=返回类型
//List={List:number[],add:(v:number)=>void,remove:(v:number)=>void,…blahblah}

如果您可以更改函数定义,我发现了一种很好且简单的方法来实现这一点。 在我的例子中,我需要将typescript类型
Parameters
与一个泛型函数一起使用,确切地说,我正在尝试
Parameters
,但实际上它不起作用。因此,实现这一点的最佳方法是通过接口函数定义更改函数定义,这也适用于typescript类型
ReturnType

以下是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);
函数foo(e:T):T{ 返回e; } 类型fooreurn=ReturnType;//该死它抛出错误 //但如果您尝试将函数定义为这样的接口: 接口foo{ (e:T):T } type fooreurn=ReturnType//它是数字,它可以工作!!! 输入fooParams=Parameters//它也可以工作!!它是[字符串] //你可以这样使用这个界面 常量myfoo:foo=(asd:number)=>{ 返回asd; }; 美孚(7);
这是我目前正在工作的解决方案,用于提取导入库(如knex)的未导出内部类型:

//foo是一个导入的函数,我无法控制它
函数foo(e:T):内部类型{
返回e;
}
类包装器{
//wrapped没有显式的返回类型,因此我们可以推断它
包装(e:T){
返回foo(e)
}
}
类型foointernationtype=ReturnType
类型Y=内部类型
//Y===内部类型
const wrapperFoo=(process.env.NODE_env====“development”?foo():未定义)!
type Return=typeof wrapperFoo

我甚至会使用
test
或一些像
typescript\u helper
这样的随机字符串(只要typescript不抛出错误),而不是
NODE\u ENV
development
,这样它就不会执行,因为它不会在运行时使用。

可能会重复一些小的修正,
type fooreurn=ReturnType
yeilds
unknown
。这个例子非常无用。您需要知道返回类型,才能使用
GenericReturnType
获取返回类型。这不是一个好的解决方案,因为它假定手头的函数只有一个泛型类型。您也可以在泛型函数中使用此技术<代码>函数foobar{const wrapperGetList=()=>getList();type List=ReturnType;…}可能我误解了什么,但看起来这个TS代码不正确。因为
interface Wrapper
不能包含
returnfoo(e)
,因为它不是“类型代码”,我的意思是它是真正的命令式代码,而不是元代码。我试图以不同的方式改变它,但徒劳无功。编译器要求我手动设置
wrapped(e:T)
的返回类型,并将随后的
{
作为错误加下划线。顺便说一句,如果我们将
接口
替换为
。Thx用于ideaOops!感谢您指出错误。
// 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>