2

I have something like this;

TestBase.ts

export class TestBase {
    static myValue: boolean;
    constructor() {
        TestBase.myValue = true;
    }
}

Test

import {TestBase} from './TestBase'

export class Test extends TestBase {
    constructor() {
        super();
    }
}

SomeOtherClass.ts

import {Test} from './Test';
import {TestBase} from './TestBase';

export class SomeOtherClass {
    constructor() {
        var test = new Test();
        console.log(Test.myValue); // undefined
        Test.myValue = false;
        console.log(Test.myValue, TestBase.myValue); // false, true
    }
}

My IDE is suggesting that myValue is available on Test, but at runtime it does not reflect the value of TestBase.myValue. Is the IDE incorrectly suggesting that static property inheritance is allowed, or is browserify/tsify breaking something?

Stafford Williams
  • 9,696
  • 8
  • 50
  • 101

5 Answers5

0

I do not think it is related to typescript, and your IDE is correct. Static members are inherited (link). I have tried your sample in node.js environment as well as in chrome browser and it outputs

true

false, true

as expected. So I guess you are correct assuming something else messing up things, maybe browserify.

Community
  • 1
  • 1
Amid
  • 21,508
  • 5
  • 57
  • 54
  • If the property is static, isn't the second line's output expected to be `true, true`? – Stafford Williams Mar 23 '16 at 07:16
  • Not in Typescript, due to how it is compiled in javascript (es5 - using prototypes, and es6 - classes). One more observation I noticed: in my tests above i was targeting ES6, but if I target ES5 (for example run code in typescript playground) - I will get the 'undefined' in output as you did. So I would say its a discrepancy between compilation to ES5 and ES6, maybe bug? – Amid Mar 23 '16 at 07:55
  • In that case, isn't the IDE incorrect, considering the property should not be available on the child class? – Stafford Williams Mar 23 '16 at 08:15
  • I think that according to the specs the property should be in child class as it is inherited (although static inheritance behaves differently from C#) - so IDE is correct. The only misbehavior I see is the 'undefined' vs 'true' when compiled for the different targets. – Amid Mar 23 '16 at 08:18
  • "static inheritance behaves differently from c#" - I think that is what i'm missing here. Can you point out a link that describes this, or a section of the spec? – Stafford Williams Mar 23 '16 at 08:35
  • I have not found explicit specification of this in specs (would be glad if someone points this out), but in the spec link I have provided it explicitly says - all members are inherited including static ones (unlike C# where static members are not inherited). Taking into account this (and looking into compiled js:)) we can justify behavior you encounter. – Amid Mar 23 '16 at 08:42
0
class TestBase {
    static myValue: boolean;
    constructor() {
        TestBase.myValue = true;
    }
}

class Test extends TestBase {
    constructor() {
        super();
    }
}

class SomeOtherClass {
    constructor() {
        var test = new Test();
        console.log(Test.myValue); // undefined
        Test.myValue = false;
        console.log(Test.myValue, TestBase.myValue); // false, true
    }
}

class HelloWorld{
    public static main(){
        let some = new SomeOtherClass();
    }
}
HelloWorld.main();

I think it is undefined because only initialized when the constructor is called, for that class.

Change by this.

class TestBase {
        static myValue: boolean = true;
        constructor() {
            TestBase.myValue = true;
        }
    }

        console.log(Test.myValue); // true
        Test.myValue = false;
        console.log(Test.myValue, TestBase.myValue); // false, true

you probably already know, but you do not need to build an object to call a static member.

At first time, Test.myValue and TestBase.myValue is undefined, when you build an object var test = new Test();. That happens to be true for that class TestBase change in constructor, TestBase.myValue = true;, but not for Test, because you access Test.myValue statically or TestBase.myValue, and TestBase.myValue after creating the object to be changed but not in Test.

Applied to the original code:

class SomeOtherClass {
    constructor() {

        console.log(Test.myValue);     // undefined
        console.log(TestBase.myValue); // undefined

        var test = new Test();

        console.log(Test.myValue);     // undefined
        console.log(TestBase.myValue); // true
    }
}
Angel Angel
  • 19,670
  • 29
  • 79
  • 105
0

In Typescript, static primitives are not inherited in the way I was expecting, however static objects are. I was able to work around the issue by holding the value inside an object;

TestBase.ts

export class TestBase {
    static someObject = { myValue: boolean };
    constructor() {
        TestBase.someObject.myValue = true;
    }
}

Test

import {TestBase} from './TestBase'

export class Test extends TestBase {
    constructor() {
        super();
    }
}

SomeOtherClass.ts

import {Test} from './Test';
import {TestBase} from './TestBase';

export class SomeOtherClass {
    constructor() {
        var test = new Test();
        console.log(Test.someObject.myValue); // true
        Test.myValue = false;
        console.log(Test.someObject.myValue, TestBase.someObject.myValue); // false, false
    }
}
Stafford Williams
  • 9,696
  • 8
  • 50
  • 101
-1

You simply cannot inherit static properties or methods.

Slava Shpitalny
  • 3,965
  • 2
  • 15
  • 22
  • I think that's not true, if not why he can do Test.myValue?, when myValue is declared in TestBase. – Angel Angel Mar 23 '16 at 11:27
  • I'm not sure what ide he uses, but it should fail compilation. Because static property compiles to nothing actually. The property sits on the function `TestBase` itself and not on its prototype so there is no inheritance – Slava Shpitalny Mar 23 '16 at 11:36
-2

It's class level properties trying as member level instance won't work. We need declare as member instance and initialize as member instance instead class object

export class TestBase {
    static myValue: boolean;
    constructor() {
        this.myValue = true;
    }
}