我有以下函数:
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
。
编辑
从 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[]
const fnReturnType = (false as true) && fn();
它的工作原理是将false
转换为true
的字面值,这样类型系统会认为返回值是函数的类型,但实际运行代码时,它会在false
处短路。
ReturnType<typeof fn>
(答案暗示 ReturnType<fn>
即可)。 - spacek33zPromise<Type>
中提取 Type
吗?这是返回值的常见情况。 - YakovLtype promiseType = Awaited<ReturnType<typeof promiseFn>>;
。 - dr497在TypeScript 2.8中最简单的方法:
const foo = (): FooReturnType => {
}
type returnType = ReturnType<typeof foo>;
// returnType = FooReturnType
使用内置的ReturnType
:
type SomeType = ReturnType<typeof SomeFunc>
ReturnType
扩展为:
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
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;
编辑:这在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; }
ReturnType<F>
来获取函数的返回类型。 :) - Aaron Beall目前还没有一种方法可以做到这一点(请参见https://github.com/Microsoft/TypeScript/issues/6606以查看跟踪添加此功能的工作项)。
一个常见的解决方法是编写类似以下内容的代码:
var dummy = false && test();
type t2 = typeof dummy;
!1
而不是false
很容易地欺骗TypeScript-- http://www.typescriptlang.org/play/#src=function%20f()%3A%20string%20%7B%0A%20return%20%2742%27%0A%7D%0A%0Alet%20a%20%3D%20!1%20%26%26%20f()%0Alet%20b%3A%20typeof%20a%20%3D%20%27abc%27 - DanielM!0
而不是!1
。这使得上面的例子对我有效。话虽如此,这种方法的一个副作用是你需要调用test()
函数才能获取类型。如果test
是一个有副作用或者开销很大的函数,那么这将导致错误或性能问题。 - KhalilRavannafunction 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
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
就足够了。 - Aaron Beallclass MeaningOfLife {
public get() {
return 42 as const;
}
}
export type Answer = ReturnType<typeof MeaningOfLife.prototype.get>; // equals the literal 42