typescript 获取函数的返回类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36015691/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Obtaining the return type of a function
提问by rid
I have the following function:
我有以下功能:
function test(): number {
return 42;
}
I can obtain the type of the function by using typeof
:
我可以通过使用获取函数的类型typeof
:
type t = typeof test;
Here, t
will be () => number
.
在这里,t
将() => number
。
Is there a way to obtain the return type of the function? I would like t
to be number
instead of () => number
.
有没有办法获取函数的返回类型?我想t
是number
不是() => number
。
回答by thedayturns
EDIT
编辑
As of TypeScript 2.8 this is officially possible with ReturnType<T>
.
从 TypeScript 2.8 开始,这在ReturnType<T>
.
type T10 = ReturnType<() => string>; // string
type T11 = ReturnType<(s: string) => void>; // void
type T12 = ReturnType<(<T>() => T)>; // {}
type T13 = ReturnType<(<T extends U, U extends number[]>() => T)>; // number[]
See herefor details.
有关详细信息,请参见此处。
TypeScript is awesome!
打字稿太棒了!
Old-school hack
老派黑客
Ryan's answer doesn't work anymore, unfortunately. But I have modified it with a hack which I am unreasonably happy about. Behold:
不幸的是,瑞安的回答不再有效。但是我已经用 hack 修改了它,我对此感到非常高兴。看:
const fnReturnType = (false as true) && fn();
It works by casting false to the literal value of true, so that the type system thinks the return value is the type of the function, but when you actually run the code, it short circuits on false.
它的工作原理是将 false 转换为 true 的字面值,以便类型系统认为返回值是函数的类型,但是当您实际运行代码时,它会在 false 上短路。
TypeScript is the best. :D
打字稿是最好的。:D
回答by Jaroslav
The easiest way in the TypeScript 2.8:
TypeScript 2.8 中最简单的方法:
const foo = (): FooReturnType => {
}
type returnType = ReturnType<typeof foo>;
// returnType = FooReturnType
回答by eug
The code below works without executing the function. It's from the react-redux-typescript library (https://github.com/alexzywiak/react-redux-typescript/blob/master/utils/redux/typeUtils.ts)
下面的代码在不执行函数的情况下工作。它来自 react-redux-typescript 库(https://github.com/alexzywiak/react-redux-typescript/blob/master/utils/redux/typeUtils.ts)
interface Func<T> {
([...args]: any, args2?: any): T;
}
export function returnType<T>(func: Func<T>) {
return {} as T;
}
function mapDispatchToProps(dispatch: RootDispatch, props:OwnProps) {
return {
onFinished() {
dispatch(action(props.id));
}
}
}
const dispatchGeneric = returnType(mapDispatchToProps);
type DispatchProps = typeof dispatchGeneric;
回答by Ryan Cavanaugh
There isn't a way to do this (see https://github.com/Microsoft/TypeScript/issues/6606for the work item tracking adding this).
没有办法做到这一点(请参阅https://github.com/Microsoft/TypeScript/issues/6606以了解添加此内容的工作项跟踪)。
A common workaround is write something like:
一种常见的解决方法是编写如下内容:
var dummy = false && test();
type t2 = typeof dummy;
回答by Aaron Beall
Edit:This is not needed with TS 2.8 any more! ReturnType<F>
gives the return type. See accepted answer.
编辑:这在 TS 2.8 中不再需要了!ReturnType<F>
给出返回类型。请参阅接受的答案。
A variant on some of the previous answers that I'm using, which works in strictNullChecks
and hides the inference gymnastics a bit:
我正在使用的一些先前答案的一个变体,它在strictNullChecks
推理体操中起作用并稍微隐藏了它:
function getReturnType<R>(fn: (...args: any[]) => R): R {
return {} as R;
}
Usage:
用法:
function foo() {
return {
name: "",
bar(s: string) { // doesn't have to be shorthand, could be `bar: barFn`
return 123;
}
}
}
const _fooReturnType = getReturnType(foo);
export type Foo = typeof _fooReturnType; // type Foo = { name: string; bar(s: string): number; }
It doescall the getReturnType
function, but it does notcall the original function. You couldprevent the getReturnType
call using (false as true) && getReturnType(foo)
but IMO this just makes it more confusing.
它确实调用了getReturnType
函数,但不调用原始函数。您可以阻止getReturnType
呼叫使用,(false as true) && getReturnType(foo)
但 IMO 这只会让它更加混乱。
I just used this method with some regexp find/replace to migrate an old Angular 1.x project that had ~1500 factory functions written like this, originally in JS, and added the Foo
etc types to all uses... amazing the broken code one will find. :)
我只是使用这种方法和一些正则表达式查找/替换来迁移一个旧的 Angular 1.x 项目,该项目有大约 1500 个这样编写的工厂函数,最初是在 JS 中,并将Foo
等类型添加到所有用途......会发现。:)
回答by John Weisz
If the function in question is a method of a user defined class, you can use method decoratorsin conjuction with Reflect Metadatato determine the return type (constructor function) at runtime(and with it, do as you see fit).
如果有问题的函数是用户定义类的方法,您可以将方法装饰器与Reflect Metadata结合使用,以确定运行时的返回类型(构造函数)(并使用它,按您认为合适的方式进行)。
For example, you could log it to the console:
例如,您可以将其记录到控制台:
function logReturnType(
target: Object | Function,
key: string,
descriptor: PropertyDescriptor
): PropertyDescriptor | void {
var returnType = Reflect.getMetadata("design:returntype", target, key);
console.log(returnType);
}
Just snap this method decorator on a method of your choice and you have the exact reference to the constructor function of the object that is supposedly returned from the method call.
只需在您选择的方法上捕捉这个方法装饰器,您就可以准确引用对象的构造函数,该对象的构造函数应该是从方法调用中返回的。
class TestClass {
@logReturnType // logs Number (a string representation)
public test(): number {
return 42;
}
}
There are a few notable limitations to this approach, however:
但是,这种方法有一些明显的局限性:
- you need to explicitly define the return type on a method decorated as such, otherwise you'll get undefined from
Reflect.getMetadata
, - you can only reference actual types which also exist after compilation; that is, no interfaces or generics
- 您需要在这样装饰的方法上显式定义返回类型,否则您将从中获得 undefined
Reflect.getMetadata
, - 您只能引用编译后也存在的实际类型;也就是说,没有接口或泛型
Also, you'll need to specify the following command line arguments for the typescript compiler, because both decorators and reflect metadata are experimental features as of writing this post:
此外,您需要为打字稿编译器指定以下命令行参数,因为在撰写本文时,装饰器和反射元数据都是实验性功能:
--emitDecoratorMetadata --experimentalDecorators
回答by Luka Jacobowitz
There's no way of retrieving the return type of the function without executing it sadly. This is because when TypeScript gets compiled into JS, you lose all information regarding type.
没有办法在不悲伤地执行它的情况下检索函数的返回类型。这是因为当 TypeScript 被编译成 JS 时,你会丢失所有关于类型的信息。
回答by Werner de Groot
I came up with the following, which seems to work nicely:
我想出了以下内容,这似乎很好用:
function returnType<A, B, Z>(fn: (a: A, b: B) => Z): Z
function returnType<A, Z>(fn: (a: A) => Z): Z
function returnType<Z>(fn: () => Z): Z
function returnType(): any {
throw "Nooooo"
}
function complicated(value: number): { kind: 'complicated', value: number } {
return { kind: 'complicated', value: value }
}
const dummy = (false as true) && returnType(complicated)
type Z = typeof dummy