Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript class inheritance: override ko.computed method

I have simple classes:

/// <reference path="..\typings\jquery\jquery.d.ts"/>
/// <reference path="..\typings\knockout\knockout.d.ts"/>

module Some.Namespace {

    export class TestBase {
        public field1: KnockoutObservable<string> = ko.observable("");

        public onFieldChange: KnockoutComputed<string> = ko.computed(() => {
            return this.field1();
        }, this);
    }

    export class Test extends TestBase {
        public field2: KnockoutObservable<string> = ko.observable("");

        public onFieldChange() {
            super.onFieldChange() + this.field2();
        }
    }
}

Problem, typescript doesn't allow to use keyword super in overridden method. It says:

Error 1 Class 'Some.Namespace.Test' cannot extend class 'Some.Namespace.TestBase': Class 'Some.Namespace.Test' defines instance member function 'onFieldChange', but extended class 'Some.Namespace.TestBase' defines it as instance member property.

Error 2 Only public methods of the base class are accessible via the 'super' keyword.

How can I override knockout computed method and don't loose base method?

like image 365
VikciaR Avatar asked Dec 27 '13 20:12

VikciaR


1 Answers

You cannot access a parent instance member property from a child class in TypeScript if you define the same name yourself. e.g. the following:

class TestBase {
    public field1;
    public onFieldChange = () => { // we need a way to reference this in the child
        return this.field1();
    };
}

class Test extends TestBase {

    parentOnFieldChange:any;
    constructor(){
        super(); // call super 

        // Implictly initialize local properties

        // copies local version not parent
        this.parentOnFieldChange = this.onFieldChange;
    }

    public field2;
    public onFieldChange = () => {
        this.parentOnFieldChange() + this.field2();
    }
}

generates (segment) :

 function Test() {
        var _this = this;
        _super.call(this); // call super

        // NO WAY to put code here 

        // Implictly initialize local properties
        this.onFieldChange = function () {
            _this.parentOnFieldChange() + _this.field2();
        };

        // OUR code on only added after

        // copies local version not parent
        this.parentOnFieldChange = this.onFieldChange;
    }

Solution Use instance member functions:

class TestBase {
    public field1;

    public onFieldChange() {
        return this.baseOnFieldChange();
    }

    private baseOnFieldChange = () => { // we need a way to reference this in the child
        return this.field1();
    };
}

class Test extends TestBase {

    parentOnFieldChange:any;
    constructor(){
        super(); // call super              
    }

    public field2;
    public onFieldChange(){
        return super.onFieldChange() + this.childOnFieldChange();
    }

    private childOnFieldChange = () => {
        return this.field2();
    }
}
like image 136
basarat Avatar answered Sep 26 '22 13:09

basarat