Skip to content

Instantly share code, notes, and snippets.

@awinogradov
Last active April 3, 2018 17:16
Show Gist options
  • Save awinogradov/e22ef5160b1a54fd2fd72010a12689f8 to your computer and use it in GitHub Desktop.
Save awinogradov/e22ef5160b1a54fd2fd72010a12689f8 to your computer and use it in GitHub Desktop.
Takie dela
function combineClasses<T1, T2>(C1, C2): new (...args: any[]) => T1 & T2 {
Object.getOwnPropertyNames(C2.prototype).forEach((name) => {
if (name !== 'constructor') {
C1.prototype[name] = C2.prototype[name];
}
});
return Object.setPrototypeOf(C2, C1);
}
function compose<T>(...args: Array<new (...args: any[]) => T>): new (...args: any[]) => T {
let ResultClass = args.splice(0, 1)[0];
function applyMixins(mixins) {
for (const Mixin of mixins) {
ResultClass = combineClasses<T, T>(ResultClass, Mixin);
}
}
applyMixins(args);
return ResultClass;
}
describe('Compose:', () => {
it('should apply mixins', () => {
interface IMyBlock {
name: string;
}
class MyBlock {
public block = 'MyBlock';
protected a: string;
constructor(props: IMyBlock) {
this.a = props.name;
}
public tag(props, state) {
return 'a';
}
public attrs(props, state): any {
return {};
}
}
class MyBlockMod11 extends MyBlock {
public tag(props, state) {
return 'b';
}
}
class MyBlockMod12 extends MyBlockMod11 {
public tag(props, state) {
return 'c' + super.tag(props, state);
}
public attrs() {
return { id: 'the-id' };
}
}
class MyBlockMod21 extends MyBlock {
public b: string;
constructor(props) {
super(props);
this.b = this.a + '1';
}
public attrs(props, state) {
return { name: 'the-name', ...super.attrs(props, state) };
}
}
const Test = compose(MyBlock, MyBlockMod12, MyBlockMod21);
const res = new Test({ name: 1 }); // должно ругаться на невалидные опции конструктору
expect(res.tag({}, {})).toBe('cb');
expect(res.b).toBe('a1'); // НЕ должно ругаться на поле b
expect(res.attrs({}, {})).toMatchObject({
id: 'the-id',
name: 'the-name',
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment