Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing static methods from instance in Typescript

Why can't I do this? Is it due to technical limitations of Javascript/Typescript, or is this a design decision by the developers of Typescript? This same code would work fine in Java or C#.

class Test {
  static str: string = "test";
  public static getTest(): string {
    return this.str;
  }
}

//works as expected
console.log(Test.getTest());
//won't compile
var test: Test = new Test();
console.log(test.getTest());
like image 448
Glen Takahashi Avatar asked Nov 23 '15 05:11

Glen Takahashi


People also ask

Can you access a static method from an instance?

A static method cannot access a class's instance variables and instance methods, because a static method can be called even when no objects of the class have been instantiated. For the same reason, the this reference cannot be used in a static method.

How do you access static members of a class TypeScript?

The static members of a class are accessed using the class name and dot notation, without creating an object e.g. <ClassName>. <StaticMember>. The static members can be defined by using the keyword static. Consider the following example of a class with static property.

How do you call a static method in class TypeScript?

A static method uses the static keyword instead of the function keyword when we define it. Static members can be encapsulated with the public, private and protected modifiers. We call a static method directly on the class, using the class name and dot notation. We don't need to create an object instance.

Does TypeScript support static?

TypeScript was developed by Microsoft to make it easier to write large code bases. Essentially, it's just JavaScript, with static typing.


1 Answers

As @basarat says, it's just a design decision, not a technical limitation.

Actually, even though it's not possible to access test.getTest() just like you would in Java or C#, there are ways to access it:

Both Object.getPrototypeOf() (replacement to the now deprecated Object.prototype.__proto__) or Object.prototype.constructor should work:

Object.getPrototypeOf(test).constructor.getTest();

test.constructor.getTest();

Actually:

Object.getPrototypeOf(test).constructor === test.constructor; // true

Here you can see the compiled source in action:

class Test {
  static getTest() {
    return this.str;
  }
}

Test.str = 'test';

const test = new Test();

console.log(Object.getPrototypeOf(test).constructor.getTest());
console.log(test.constructor.getTest());

console.log(Object.getPrototypeOf(test).constructor === test.constructor);
console.log(Object.getPrototypeOf(test) === Test.prototype);

Note static properties exist in classes but not in instances.

Therefore, if you want to go from test to its prototype, you should call Object.getPrototypeOf(test), not test.prototype, which is a completely different thing.

The .prototype property only exists in functions and, when instantiating a new object using new and a call to that constructor function (new Test()), will become the newly created object's prototype (the deprecated .__proto__).

In your example:

test.prototype;                     // undefined
Test;                               // class Test { static getTest() { ... } }
Test.protoype;                      // { constructor: class Test { ... } }
Test.protoype.constructor;          // class Test { static getTest() { ... } }
Test.protoype.constructor === Test; // true
test.constructor;                   // class Test { static getTest() { ... } }
test.constructor === Test;          // true

Object.getPrototypeOf(test) === Test.prototype; // true
like image 169
Danziger Avatar answered Oct 09 '22 17:10

Danziger