0

Let's say I want class Warrior in my game. And my warriors can only walk.

class Warrior{

constructor(){}

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

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

Then I decided to create a weapon class so that when this class is active, my Warriors in the game can fight. Some pseudocode how I imagine it:

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!'

So I need to extend the class itself and all its instances with the new methods and parameters when some sort of magic extention code is present. Thus I can incapsulate behaviour in the separate classes and extend it to other classes without need to have noticed them.

What I saw is mixins but the idea behind that is to explicit change my Warrior class to incapsulate new functions. I can't just say that since now my warriors can fight, I need to change the the cases when i use Warriors to some sort of new type - FighterWarriors and that can be a real pain if I need to quickly enchance the objects with the new behaviour.

This is working technique in c# and swift but I don't know about other languages.

So the questions are: how can I make this type of behaviour in Typescript? If can't, does the pure JS supports this? What can I read additionally for this theme?

1 Answer 1

1

You can use interface merging and module augmentation to add members to a type. For the JS part, things are pretty simple you just need to add a new property on the Warrior prototype

// 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();
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! One question, do you mean Warrior.ts or Weapon.ts in the second case? It seems it should be weapon.ts.
@gleb.kudr yeah, sorry my bad

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.