15

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());

2 Answers 2

8

but I'd still like to know why.

Less magic. Static properties exist on the Class not instances. Its clear exactly what is getting called from the code instead of magic binding to class or member function at runtime.

Is it due to technical limitations of Javascript/Typescript, or is this a design decision by the developers of Typescript

Not a technical limitation. A design decision. More to align with ES6 than anything else : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static But over there its a decision made for less magic

Sign up to request clarification or add additional context in comments.

1 Comment

Updated my question to have a clearer question: Is it due to technical limitations of Javascript/Typescript, or is this a design decision by the developers of Typescript? It sounds like you're telling me its the latter to make things clearer to a developer.
7

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

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.