// https://justinfagnani.com/2015/12/21/real-mixins-with-javascript-classes/
/**
* 对于 mixin,不要在 initialize 里给字段赋值,建议直接在构造函数,或者直接字段声明的同时赋值
*/
/**
* canmove
*/
interface CanMoveContext {
name: string
}
interface CanMoveAbstract {
move(far: number): void
}
interface CanMoveOptional {
onMove(): void
}
interface CanMove {
tryMoving(): void
}
class CanMoveMixin implements CanMove {
tryMoving(): void {
this.move(90)
}
}
interface CanMoveMixin
extends CanMoveAbstract,
CanMoveOptional,
CanMoveContext {}
interface CanMoveExports extends CanMove, CanMoveOptional {}
/**
* animal
*/
type AnimalAbstract = CanMoveAbstract
interface AnimalContext extends CanMoveContext {
_parent: RealAnimal
}
interface AnimalOptional extends CanMoveOptional {
onRoar(): void
}
interface Animal {
roar(): void
}
@mix(CanMoveMixin)
class AnimalMixin implements Animal {
roar(): void {
this.move(90)
this.tryMoving()
this.onMove && this.onMove()
this.onRoar && this.onRoar()
}
}
interface AnimalMixin
extends CanMove,
AnimalContext,
AnimalOptional,
AnimalAbstract {}
interface AnimalExports extends CanMoveExports, Animal, AnimalOptional {}
class RealAnimal {
_parent: RealAnimal
age = 0
/**
* be sure `moan` has the same shape with `AnimalMixin.moan`
*/
roar(): void {}
}
@mix(AnimalMixin)
class Human extends RealAnimal implements AnimalAbstract {
move(far: number): void {
throw new Error("Method not implemented.")
}
sayWords() {}
}
interface Human extends AnimalExports {}
class Singhi extends Human {
speak() {
// this.
}
}
interface Class {
/**
* Returns the name of the function. Function names are read-only and can not be changed.
*/
readonly name: string
prototype: any
}
function mix(C0: any) {
return function (target: any) {
// mix
}
}
export { Singhi }