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
yeildsunknown
。这个例子非常无用。您需要知道返回类型,才能使用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>