Búsqueda de sitios web

typescript - La propiedad abstracta en la clase no se puede acceder en el constructor


En el siguiente ejemplo, estoy recibiendo el error de TypeScript La propiedad abstracta 'name' en la clase 'Minigame' no puede ser accedida en el constructor.

Estoy teniendo dificultades para pensar en cómo podría implementar esto. No puedo pasar el nombre de la clase concreta en la llamada a super() porque no puedo acceder a las propiedades del objeto antes de esa llamada, y no puedo hacer que las propiedades sean static porque la clase abstracta no puede exigir eso.

¿Cómo debería organizarse esto para garantizar que cada Minigame instancie un objeto Explanation, que requiere la propiedad de nombre de la clase concreta? ¿Realmente es mi mejor opción hacer que el nombre sea static (y eliminar el requisito abstracto) para mantenerlo 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();
    }
}

Respuesta #1

Es un poco feo para una cadena, pero podrías hacer:

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();
    }
}

Respuesta #2

Aquí hay otra solución basada en Tom Coton que no obliga a implementar el método getName.

Simplemente moviendo el name en la clase abstracta como argumento del constructor.

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 })

puedes comprobar aquí haciendo clic en "Ejecutar"

https://www.typescriptlang.org/play?#code/MYGwhgzhAECiAeAHcA7MAXAlgexdA3gLABQ0Z0aAtgKYBc0E6ATpigOYDcJ50wujTAK7B02JgAoqdBs1ZsAlAW49y6ABaYIAOinQAvBTA0upcgF8SF4iTAAjAWBG9wUaAFlWmNkepLTZaiRUDBwUegRkMDQsXA5yZTIpegE5Ex4+FAFhUQkkmRZ2RXxoBJV1TR0ffUNjUp5y7UDI6NDqlGoAdzggqJDccQbKmnk080sS62JQSBgAZWwaAHEqwPRqFAATGA8ULyri0oyskTFxIrryCEFEagkAcggF328aO-lSqysSI-RoF98DO0uvMlj4ziZvvxsCBqFoQNg2OJiv96P9oGZ5EA

En caso de necesitar recrear el Explanation cada vez que se establezca el name, podrías usar setters y getters además:

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

Artículos relacionados