typescript 获取函数的返回类型

byqmnocz  于 12个月前  发布在  TypeScript
关注(0)|答案(9)|浏览(169)

我有以下功能:

function test(): number {
    return 42;
}

字符串
我可以通过使用typeof来获得函数的类型:

type t = typeof test;


在这里,t将是() => number
有没有办法获得函数的返回类型?我希望tnumber而不是() => number

8ulbf1ek

8ulbf1ek1#

编辑

从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[]

字符串
详情请参见this pull request to Microsoft/TypeScript
TypeScript太棒了!

老派黑客

瑞安的答案不工作了,不幸的是。但我已经修改了它与黑客,我是不合理的高兴。看:

const fnReturnType = (false as true) && fn();


它的工作原理是将false转换为true的文字值,这样类型系统就认为返回值是函数的类型,但当你实际运行代码时,它会在false上短路。

qojgxg4l

qojgxg4l2#

在TypeScript 2.8中最简单的方法:

const foo = (): FooReturnType => {
}

type returnType = ReturnType<typeof foo>;
// returnType = FooReturnType

字符串

d6kp6zgx

d6kp6zgx3#

使用内置ReturnType

type SomeType = ReturnType<typeof SomeFunc>

字符串
ReturnType扩展为:

type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;

r6hnlfcb

r6hnlfcb4#

下面的代码不需要执行函数就可以工作。它来自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;

字符串

gj3fmq9x

gj3fmq9x5#

没有办法做到这一点(请参阅https://github.com/Microsoft/TypeScript/issues/6606了解添加此功能的工作项跟踪)。
一个常见的解决方法是写这样的东西:

var dummy = false && test();
type t2 = typeof dummy;

字符串

qmb5sa22

qmb5sa226#

  • 编辑:* 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函数,但它并没有调用原来的函数。你可以使用(false as true) && getReturnType(foo)来阻止getReturnType的调用,但在我看来,这只会让它更加混乱。
我只是使用这个方法和一些regexp find/replace来迁移一个旧的Angular 1.x项目,这个项目有大约1500个像这样写的工厂函数,最初是在JS中,并添加了Foo等类型来使用所有用途......令人惊讶的是,你会发现坏掉的代码。

5q4ezhmt

5q4ezhmt7#

如果所讨论的函数是用户定义类的方法,您可以使用方法装饰器结合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得到undefined,
  • 只能引用编译后仍然存在的实际类型;也就是说,没有接口或泛型

此外,你需要为typescript编译器指定以下命令行参数,因为装饰器和反射元数据都是在写这篇文章时的实验性功能:

--emitDecoratorMetadata --experimentalDecorators

ifmq2ha2

ifmq2ha28#

我想出了以下方法,看起来效果不错:

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

字符串

ct3nt3jp

ct3nt3jp9#

如果你有一个类,你想得到一个方法的返回类型:

class MeaningOfLife {
  public get() {
    return 42 as const;
  }
}

字符串
您可以访问类的原型,以便将方法作为函数获取:

export type Answer = ReturnType<typeof MeaningOfLife.prototype.get>; // equals the literal 42


这是非常好的,因为有时TypeScript能够推断复杂类型分析代码

相关问题