44

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!

2
  • That's probably the way to do it Commented Jul 20, 2017 at 8:37
  • But if this is done from outside the class, it will only work for public members. Commented Jul 20, 2017 at 9:15

4 Answers 4

57

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;
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

This is a cleaner solution compared to accepted answer, however it won't work if MyClass has generic type MyClass<T>. It's easier to just use MyClass<T>['method']
26

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.

Comments

15

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;
  }
}

2 Comments

Can it be simplified to be just MyClass["myMethod"]? Is there any obvious drawback doing it this way as opposed to the one in the answer?
I think you'd have to write something similar to what Nitzan Tomer suggests in his answer: typeof MyClass.prototype.myMethod. I don't see drawbacks - just a different way to achieve this same thing.
8

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.