我有以下功能:
function test(): number {
return 42;
}
我可以通过使用获取函数的类型typeof
:
type t = typeof test;
在这里,t
将是() => number
。
有没有办法获取函数的返回类型?我想t
是number
不是() => number
。
我有以下功能:
function test(): number {
return 42;
}
我可以通过使用获取函数的类型typeof
:
type t = typeof test;
在这里,t
将是() => number
。
有没有办法获取函数的返回类型?我想t
是number
不是() => number
。
Answers:
编辑
从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[]
有关详细信息,请参见此处。
TypeScript很棒!
老派骇客
不幸的是,Ryan的答案不再起作用。但是我用一个骇客修改了它,对此我感到不愉快。看哪:
const fnReturnType = (false as true) && fn();
它通过将false转换为true的字面值来工作,以便类型系统认为返回值是函数的类型,但是当您实际运行代码时,它将在false上短路。
TypeScript是最好的。:D
Cannot find name 'ReturnType'
?使用vscode
ReturnType<typeof fn>
(答案意味着ReturnType<fn>
足够了)。
下面的代码在不执行功能的情况下起作用。它来自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;
无法执行此操作(请参阅https://github.com/Microsoft/TypeScript/issues/6606以了解添加此工作项的工作项)。
常见的解决方法是编写如下内容:
var dummy = false && test();
type t2 = typeof dummy;
编辑: TS 2.8不再需要此功能!ReturnType<F>
给出返回类型。请参阅接受的答案。
我正在使用的某些先前答案的一种变体,可在某种程度上起作用strictNullChecks
并隐藏推理体操:
function getReturnType<R>(fn: (...args: any[]) => R): R {
return {} as R;
}
用法:
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; }
它会调用该getReturnType
函数,但不会调用原始函数。您可以使用阻止getReturnType
呼叫,(false as true) && getReturnType(foo)
但是IMO只会使呼叫更加混乱。
我只是使用此方法和一些正则表达式查找/替换来迁移一个旧的Angular 1.x项目,该项目最初以JS编写了约1500个工厂函数,并在Foo
所有用法中添加了etc类型...会发现。:)
ReturnType<F>
用来获取函数返回类型。:)
test
。这个答案是比较有用的一个只重命名test
,以foo
(诚然产生更复杂的返回类型,踢)。如果您已经知道如何将其应用于原始示例,那么接受的答案和您的评论都可能很棒。(这里已经很晚了,对我来说,完整的ReturnType示例的语法看起来并不立刻。)
如果所讨论的函数是用户定义的类的方法,则可以将方法装饰器与Reflect Metadata结合使用,以在运行时确定返回类型(构造函数)(并按照自己的意愿进行操作)。
例如,您可以将其记录到控制台:
function logReturnType(
target: Object | Function,
key: string,
descriptor: PropertyDescriptor
): PropertyDescriptor | void {
var returnType = Reflect.getMetadata("design:returntype", target, key);
console.log(returnType);
}
只需将此方法装饰器捕捉到您选择的方法上,您就可以正确地引用应该从方法调用返回的对象的构造函数。
class TestClass {
@logReturnType // logs Number (a string representation)
public test(): number {
return 42;
}
}
但是,此方法有一些明显的局限性:
Reflect.getMetadata
,另外,您需要为Typescript编译器指定以下命令行参数,因为在撰写本文时,装饰器和反射元数据都是实验性功能:
--emitDecoratorMetadata --experimentalDecorators
如果不悲伤地执行它,就无法检索该函数的返回类型。这是因为当TypeScript编译为JS时,您会丢失所有与类型有关的信息。
ReturnType<T>
已经在TypeScript中实现,这更加明显。
我想出了以下方法,它看起来很好用:
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
fn: (...args: any[]) => Z
是你所需要的全部。