Akidi
Akidi

Reputation: 935

typescript extend base class object property

First and foremost, I apologize, I'm completely new to OO programming and I'm sure there is a better way to word this question ( one that would probably yield a search result or 10 ).

So to make my life easy and to explain what I want to do here's code

class A {
  propertyA = {
    itemA: "a",
    itemB: "b".
    itemC: "c"
  }
  propertyB = {
    itemA: "A"
  }
}
class B extends A {
  propertyA.itemD = "d";
  propertyB.itemB = "B";
}

I get an error when I try to do this. I basically need the base class to be a template and extend a few things here and there with the extending class. Otherwise it only needs all the other properties ( I just don't want to retype them for each class )

Upvotes: 5

Views: 26290

Answers (4)

Niels Steenbeek
Niels Steenbeek

Reputation: 4834

Since the accepted answer is TypeScript without Typings, I felt the need to show an example having Typings.

    interface PropertyA {
      itemA?: string;
      itemB?: string;
      itemC?: string;
    }

    class A {
      propertyA: PropertyA = {
        itemA: "a",
        itemB: "b".
        itemC: "c"
      }
    }

    interface PropertyAextended extends PropertyA {
      itemD?: string;
    }

    class B extends A {
      // This will prevent TS2339: Property 'itemD' does not exist on type 'PropertyA'.
      propertyA: PropertyAextended;

      constructor(){
        super();
        this.propertyA.itemD = "d";
      }
    }


    const x = new B();
    console.log(x.propertyA.itemD);

Upvotes: 4

Hannes Dahlberg
Hannes Dahlberg

Reputation: 21

Not sure if this is the correct way of solving it but this is what I ended up with:

class A {
    propertyA: any = {
        itemA: 'a',
        itemB: 'b',
        itemC: 'c'
    }
    propertyB: any = {
        itemA: 'A'
    }
}
class B extends A {
    propertyA: any = {
        ...this.propertyA,
        ...{
            itemD: 'd'
        }
    };
    propertyB: any = {
        ...this.propertyB,
        ...{
            itemB: 'B'
        }
    }
}

A new instance of class B will have { itemA: 'a', itemB: 'b', itemC: 'c', itemD: 'd' } as propertyA and { itemA: 'A', itemB: 'B' } as propertyB

Upvotes: 2

Precastic
Precastic

Reputation: 4001

The accepted answer still gave me typescript warnings when typing my object properties. You can suppress property does not exist on type warnings if you have the option to completely re-declare the parent object's property, as follows:

class A {

  propertyA: {
    itemA: string
  } = {
    itemA: '123'
  };

}

class B extends A {

  propertyA: {
    itemA?: string, // Need to re-declare this
    itemB?: string
  } = {
    itemA: '123', // Need to re-initialise this
    itemB: '456'
  };

}

This works best if you don't initialise properties when they are declared but instead in the constructor or other methods if possible. This then means that you don't need to know what class A initialises the property to unless you specifically override it:

class A {

  propertyA: {
    itemA?: string
  } = {};

  constructor() {
    this.propertyA.itemA = '123'; // Now we don't need to do this in derived classes
  }

}

class B extends A {

  propertyA: {
    itemA?: string, // Need to re-declare this
    itemB?: string
  } = {};

  constructor() {
    super();
    this.propertyA.itemB = '456';
  }

}

Upvotes: 4

Murhaf Sousli
Murhaf Sousli

Reputation: 13296

This is how you do it in typescript

class A {
  propertyA = {
    itemA: "a",
    itemB: "b".
    itemC: "c"
  }
  propertyB = {
    itemA: "A"
  }
}
class B extends A {
  constructor(){
     super();
     this.propertyA.itemD = "d";
     this.propertyB.itemB = "B";
  }
}


var x = new B();
console.log(x.propertyA.itemD);

Upvotes: 7

Related Questions