In the following example, I'm getting the TypeScript error Abstract property 'name' in class 'Minigame' cannot be accessed in the constructor.
I'm struggling to think how I could implement this. I can't pass the concrete class' name into the super()
call because I can't access properties of the object before that call, and I can't make the properties static
because the abstract class can't enforce that.
How should this be organized to guarantee every Minigame
instantiates an Explanation
object, which requires the concrete class' name property? Is making the name static
(and removing the abstract requirement) really my best option to keep it simple?
abstract class Minigame {
abstract name: string;
explanation: Explanation;
constructor() {
this.explanation = new Explanation(this.name);
}
}
class SomeGame extends Minigame {
name = "Some Game's Name";
constructor() {
super();
}
}
Here another solution based on Tom Coton which does not forces to implement the getName
method.
Just moving the name
in abstract class as constructor argument.
class Explanation {
name: string;
constructor(name: string) {
this.name = name;
}
}
abstract class Minigame {
explanation: Explanation;
name: string;
constructor(name) {
this.name = name;
this.explanation = new Explanation(this.name);
}
}
class SomeGame extends Minigame {
constructor() {
super('some game')
}
}
const game = new SomeGame();
console.log({ game: game })
you can check here by clicking in "Run"
In case of needing to re-create the Explanation
every time the name
is set you could use setter & getters in addition:
class Explanation {
name: string;
constructor(name: string) {
this.name = name;
}
}
abstract class Minigame {
explanation?: Explanation;
private _name?: string;
set name(name: string | undefined) {
this._name = name;
if(name) {
this.explanation = new Explanation(name);
}
}
get name(): string | undefined{
return this._name;
}
constructor(name?: string) {
this.name = name;
}
}
class SomeGame extends Minigame {
constructor() {
super('some game');
}
}
const game = new SomeGame();
console.log({ game: game })