Markus Mauch
Markus Mauch

Reputation: 1283

TypeScript: get type of instance method of class

I'm trying to get the type of an instance method of a class. Is there a built-in (better) way other than looking up the type in the prototype of the class?

class MyClass
{
    private delegate: typeof MyClass.prototype.myMethod; // gets the type ( boolean ) => number;

    public myMethod( arg: boolean )
    {
        return 3.14;
    }
}

Thanks in advance!

Upvotes: 42

Views: 25753

Answers (4)

Dmitry Minkovsky
Dmitry Minkovsky

Reputation: 38143

A simple, idiomatic approach appears to be:

type MyMethodType = MyClass['myMethod'];

It doesn't seem to have any downsides, and, as @cuddlefish points out, it also works if MyClass is generic.

Upvotes: 24

Dmitry Efimenko
Dmitry Efimenko

Reputation: 11203

you can use the following type:

type TypeOfClassMethod<T, M extends keyof T> = T[M] extends Function ? T[M] : never;

With that, you can write the following:

class MyClass
{
  private delegate: TypeOfClassMethod<MyClass, 'myMethod'>; // gets the type (boolean) => number;

  public myMethod( arg: boolean )
  {
    return 3.14;
  }
}

Upvotes: 14

ronif
ronif

Reputation: 805

You could use TypeScript's built in InstanceType for that:

class MyClass
{
  private delegate: InstanceType<typeof MyClass>['myMethod']; // gets the type (boolean) => number;

  public myMethod( arg: boolean )
  {
    return 3.14;
  }
}

Upvotes: 52

Nitzan Tomer
Nitzan Tomer

Reputation: 164147

If you want to have a private method but still being able to pull this trick and have it have exposed as public then you can do this:

class MyClass {
    public myMethodType: typeof MyClass.prototype.myMethod;

    private myMethod(arg: boolean) {
        return 3.14;
    }
}

let fn: typeof MyClass.prototype.myMethodType;

That compiles to:

var MyClass = (function () {
    function MyClass() {
    }
    MyClass.prototype.myMethod = function (arg) {
        return 3.14;
    };
    return MyClass;
}());
var fn;

As you can see, the myMethodType member isn't part of the compiled js, which is good because it's only used for its type.

Upvotes: 8

Related Questions