Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subclassing in Typescript

I have a storage class in Typescript, that implements Storage interface, say MyStorage. But it has too many methods, so I want to use it instead of MyStorage.getCandy - MyStorage.Candies.getCandies. How can the structure possibly look?

I assume, something like

export class MyStorage implements Storage {

public constructor {} ...

Candies: {
   getCandies() { ... }
}

Balls: {
...
}
}
like image 963
annaoomph Avatar asked Aug 20 '18 12:08

annaoomph


2 Answers

You should consider whether such a huge object makes sense. Classes that do everything are generally a bad idea, you should split them up in several classes that each deals with a specific object type (ie one class for Balls, one for Candies etc.) and use those classes. If you want to share code you can put it in a base class (preferably an abstract base class if it has no concrete functionality). A solution might look like this:

export abstract class MyStorage implements Storage { 

}
export class CandiesStorage extends MyStorage { 
    getCandies() {}
}

export class BallsStorage extends MyStorage { 
}

That being said, if for your own reasons this is not feasible, you can split up the functions like this, you just have the operator wrong, you need to initialize the Candies field with = not with : (: is a type annotation not field initialization inside a class). One problem with this approach is that inside the object literal functions (for example getCandies), this will refer to the object literal if you use regular functions. The simplest solution would be to use an arrow function or to add an extra owner field to allow access to the containing class instance. Here is a solution that exemplifies both options:

export class MyStorage implements Storage {

    public constructor (){ }

    Candies = {
        getCandies: () => {
            this.Balls // this refers to MyStorage
        }
    }

    Balls = { 
        owner: this, // capture the owner object in a field
        getBalls() {
            this.owner.Candies // this refers to the Balls objects, but we can use owner to access the container
        }
    }
} 
like image 197
Titian Cernicova-Dragomir Avatar answered Oct 14 '22 07:10

Titian Cernicova-Dragomir


You could make MyStorage and abstract class. Inside MyStorage you could have functionality that will be used/shared across all subclasses my MyStorage. Then create concrete classes that extend MyStorage which will contain specific functionality to that subclass.

Storage interface

export interface Storage {
    ...abstract interface methods.
}

Abstract storage class

export abstract class MyStorage implements Storage {
    ...shared functionality between subclasses of MyStorage
}

Concrete implementations

export class CandiesStorage extends MyStorage {
    ...your Candies specific functionality.
}

export class BallStorage extends MyStorage {
    ...your Ball specific functionality.
}
like image 41
Jason White Avatar answered Oct 14 '22 08:10

Jason White