См. Met корыто, который использует декораторов класса и дженерики, чтобы гарантировать, что вы не присвоить свойству, которое не существует в классе:
const mixin = <B>(behaviour: B) => <M extends B, TFunction extends Function>(Class: TFunction & {new(...args: Array<any>): M}) => {
Reflect.ownKeys(behaviour).forEach(key => {
if(key !== 'constructor') {
if(Class.prototype.hasOwnProperty(key))
console.warn(`Warning: mixin property overrides ${Class.name}.${key}`);
Object.defineProperty(Class.prototype, key, Object.getOwnPropertyDescriptor(behaviour, key))
}
});
return Class;
};
@mixin({
bar: 'baz'
})
class Foo {
bar: string;
}
const foo = new Foo;
console.log(Foo.prototype.bar, foo.bar, foo.hasOwnProperty('bar'));
// prints baz baz false
Наследование работает отлично и изменяет только суб-класса прототип:
@mixin({
zip: 7,
bar: 'zaz'
})
class Zoo extends Foo {
zip: number;
}
const zoo = new Zoo;
console.log(zoo.zip, zoo.bar, foo.bar);
// prints 7 zaz baz
Вы определенно не хотите определять его в конструкторе, иначе прототип будет переопределен каждый раз, когда вызывается конструктор! –
@ Александр Миллс, вы правы. Я определенно не хотел его определять в конструкторе. Спасибо за напоминание! –