打字稿或 JS class 扩展

Typescript or JS class extension

假设我想在游戏中使用 class Warrior。而我的战士只能走路。

class Warrior{

constructor(){}

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

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

然后我决定制作一个武器class,这样当这个class激活时,我在游戏中的战士就可以战斗了。我想象中的一些伪代码:

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

因此,当存在某种神奇的 extention 代码时,我需要使用新方法和参数扩展 class 本身及其所有实例。因此,我可以将行为封装在单独的 classes 中,并将其扩展到其他 classes 而无需注意它们。

我看到的是 mixin,但其背后的想法是显式更改我的 Warrior class 以封装新功能。我不能只是说因为现在我的战士可以战斗了,我需要将我使用 Warriors 的情况更改为某种新类型 - FighterWarriors 如果我需要用新行为快速增强对象,那将是一个真正的痛苦。

这是 c# 和 swift 中的工作技术,但我不知道其他语言。

所以问题是:如何在 Typescript 中实现这种行为?如果不能,纯JS支持吗?我可以为这个主题额外阅读什么?

您可以使用接口合并和模块扩充来向类型添加成员。对于 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();