Расширение Typescript или JS класса - PullRequest
0 голосов
/ 09 ноября 2018

Допустим, я хочу класс Warrior в моей игре. И мои воины могут только ходить.

class Warrior{

constructor(){}

walk(){
  alert ('I can walk!');
  }
}

x.walk(); //'I can walk!'
x.fight(); //error

Тогда я решил создать класс оружия, чтобы, когда этот класс активен, мои Воины в игре могли сражаться. Какой-то псевдокод, как я это себе представляю:

class Weapon{

canFight(type:Warrior){
set warrior.fight=()=>{alert('I can fight!')};}

}

let x=new Warrior();

x.walk(); //'I can walk!'
x.fight() //'I can fight!'

Поэтому мне нужно расширить сам класс и все его экземпляры новыми методами и параметрами, когда присутствует какой-то магический код расширение . Таким образом, я могу инкапсулировать поведение в отдельных классах и распространять его на другие классы без необходимости их замечать.

То, что я увидел, - это миксины, но идея заключается в том, чтобы явно изменить мой класс Warrior для инкапсуляции новых функций. Я не могу просто сказать, что, поскольку теперь мои воины могут сражаться, мне нужно изменить случаи, когда я использую Воины , на какой-то новый тип - FighterWarriors , и это может быть настоящая боль, если мне нужно быстро улучшить объекты новым поведением.

Это рабочая техника в c # и swift, но я не знаю других языков.

Итак, вопросы: как я могу сделать этот тип поведения в Typescript? Если не можете, поддерживает ли чистый JS это? Что я могу прочитать дополнительно по этой теме?

1 Ответ

0 голосов
/ 09 ноября 2018

Вы можете использовать объединение интерфейсов и расширение модулей для добавления членов в тип. Что касается JS, все довольно просто, вам просто нужно добавить новое свойство в Warrior прототип

// Warrior.ts
export class Warrior {

    constructor() { }

    walk() {
        alert('I can walk!');
    }
}
// Weapon.ts
import {Warrior } from './Warrior'

export class Weapon{
    canFight(type:Warrior){
    }
}

declare module './Warrior' {
    interface Warrior {
        fight(): void
    }
}
Warrior.prototype.fight = function (this: Warrior){
    console.log("FIGHT");
}

// Usage.ts

import {Warrior  } from './Warrior'
import './Weapon'


let x=new Warrior();
x.fight();
...