3

I want to access the static member of a class through an object of this class.

I do it using obj.constructor. It works well except with the typescript linter which says

Property 'getName' does not exist on type 'Function'

class Foo {
    public static getName(): string {
        return 'foo';
    }
}

const foo = new Foo();

const name: string = foo.constructor.getName();

I tried using : const name: string = (foo.constructor as Foo).getName();

but it gives me

Property 'getName' is a static member of type 'Foo'


EDIT :

It worked using : const name: string = (foo.constructor as typeof Foo).getName();

Is there any way it could work without manually casting the class?



INFO : I cannot call it directly using Foo.getName() in my specific case

2 Answers 2

4

Static methods are accessed by calling the constructor directly:

Foo.getName()

If for some reason you don't have access to the constructor, assert foo.constructor to be of its type.

const name: string = (foo.constructor as typeof Foo).getName();
Sign up to request clarification or add additional context in comments.

4 Comments

Thank for your input but I specifically asked to not call it directly using the class name. I would like a solution to work along with foo.constructor.
I've seen your hint just after I clicked submit. I edited my answer.
The problem with this is that if the OP has access to Foo to feed to typeof then he can just call Foo.getName()
@JaredSmith totally got it. If the answer is: it's not possible. Alright, but post the answer that way please.
1

You have to fudge it with the compiler if you don't have access to the class. Note that this is a filthy dirty hack, but sometimes you just have to tell the compiler "shut up, I know what I'm doing".

class Foo {
  public static getName() {
    return 'foo';
  }
}

const foo = new Foo();

interface FudgeIt {
  getName: () => string,
}

// compiler won't let us cast a function to
// a random interface without declaring it
// unknown first.
const c: unknown = foo.constructor;
(c as FudgeIt).getName();

Here's a link to the relevant playground

3 Comments

I see, so there is no way to implicitly say typescript that .constructor is of typeof Foo alright? Nor any other way to access the static method of an object (different than .constructor) ? If that so, I think i'll just go for the // @ts-ignore for now. Thx for your trick, it may help someone else
@GrégoryNEUT part of the problem with having an extremely flexible base language like Javascript is that the typechecker has to be very pessimistic about what can or cannot be changed out from under it. You can use the trick or not as you will but if you end up using it I'd include some explanatory comments.
I totally aggree. We are moving all our code from javascript to typescript, so we are encountering theses kind of issues. Thx for your help. We will refactor it later to be able to have the type accessible (Foo) and use it properly.

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.