When extending a class, I can easily add some new properties to it.
But what if, when I extend a base class, I want to add new properties to an object (a property which is a simple object) of the base class?
Here is an example with some code.
base class
type HumanOptions = {
alive: boolean
age: number
}
class Human {
id: string
options: HumanOptions
constructor() {
this.id = '_' + Math.random()
this.options = {
alive: true,
age: 25,
}
}
}
derived class
type WizardOptions = {
hat: string
} & HumanOptions
class Wizard extends Human{
manaLevel: number
options: WizardOptions // ! Property 'options' has no initializer and is not definitely assigned in the constructor.
constructor() {
super()
this.manaLevel = 100
this.options.hat = "pointy" // ! Property 'options' is used before being assigned.
}
}
Now, as you can see from the in-line comments, this will anger TypeScript. But this works in JavaScript. So what is the correct ts way to achive this? If there is not, is the problem in my code-pattern itself? What pattern would be suited for the problem?
Maybe you are wondering why I want those properties in a options
object. It can be very useful! For example: only the properties in the options
are be edited through some UI. So, some other code could dynamically look for the options
in the class and expose/update them on the UI, meanwhile properties like id
and manaLevel
would be left alone.
Note
I know I could do this for the wizard:
class Wizard extends Human{
manaLevel: number
options: {
hat: string
alive: boolean
age: number
}
constructor() {
super()
this.manaLevel = 100
this.options = {
alive: true,
age: 25,
hat: "pointy"
}
}
}
And it works. but then the code is not very DRY and I have to manually manage the options inheritance (which in a complex application is not ideal).