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();
}
}
It's a little ugly for a string, but you could do:
abstract class Minigame {
abstract GetName(): string;
explanation: Explanation;
constructor() {
this.explanation = new Explanation(this.GetName());
}
}
class SomeGame extends Minigame {
GetName(): string {
return "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"
https://www.typescriptlang.org/play?#code/MYGwhgzhAECiAeAHcA7MAXAlgexdA3gLABQ0Z0aAtgKYBc0E6ATpigOYDcJ50wujTAK7B02JgAoqdBs1ZsAlAW49y6ABaYIAOinQAvBTA0upcgF8SF4iTAAjAWBG9wUaAFlWmNkepLTZaiRUDBwUegRkMDQsXA5yZTIpegE5Ex4+FAFhUQkkmRZ2RXxoBJV1TR0ffUNjUp5y7UDI6NDqlGoAdzggqJDccQbKmnk080sS62JQSBgAZWwaAHEqwPRqFAATGA8ULyri0oyskTFxIrryCEFEagkAcggF328aO-lSqysSI-RoF98DO0uvMlj4ziZvvxsCBqFoQNg2OJiv96P9oGZ5EA
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 })
https://www.typescriptlang.org/play?#code/MYGwhgzhAECiAeAHcA7MAXAlgexdA3gLABQ0Z0aAtgKYBc0E6ATpigOYDcJ50wujTAK7B02JgAoqdBs1ZsAlAW49y6ABaYIAOinQAvBTA0upcgF8SF4iTAAjAWBG9wUaAFlWmNkepLTZaiRUDBwUAH56BGQwNCxcDnJlMkQWADcMXwB9KQiZFnYTJIZqdEMaSR96ATloAB9oQRQAE2oAM1ZqJsUifxV1TS1sn30y6hMVckxWippuor6NbUDo2NCRimoAdzggmJDcGep5cYnoKx4rIrYS0fF5Ktl2Oobmto6mntPoJhLBJjx+tohsYipdenwUAJhKIJDkHvkFH4voCdMMDFITmQrGZoCQSKBIDAAMrYGgAcWGgXQ1GaMA8KC8w3wuOs4P4zGhYjuSNOEEEiGoEgA5BBSb5vDQhcdQXjiGCIYxoBLfOittASeSfHdCsQFdgQNQtCBsGxxMzlfRlWd5EA
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With