Skip to content

Instantly share code, notes, and snippets.

View antongolub's full-sized avatar
😱
Living in a dystopia

Anton Golub antongolub

😱
Living in a dystopia
View GitHub Profile
type IMixinsApplier = <T extends IConstructable, U extends IConstructable[]>(target: T, ...mixins: U) => IMixedAsClass<T, U>
type IMixedAsClass<T extends IConstructable, U extends any[]> = T
& UnionToIntersectionOfConstructables<U[number]>
& IConstructable<InstanceType<T> & UnionToIntersectionOfInstances<U[number]>>
interface IConstructable<T = {}> extends Function {
new (...args: any[]): T
}
@antongolub
antongolub / IMixinApplier.ts
Last active January 17, 2020 19:47
Merge a pair of classes
type IMixinApplier = <T extends IConstructable, M extends IConstructable>(target: T, mixin: M) =>
T & M & Class<InstanceType<T> & InstanceType<M>>
@antongolub
antongolub / classType.ts
Created January 17, 2020 12:42
Class type
type Abstract<T= {}> = Function & {prototype: T}
type Constructor<T= {}> = new (...args: any[]) => T
type Class<T= {}> = Abstract<T> & Constructor<T>
@antongolub
antongolub / FooClass.ts
Last active January 17, 2020 19:53
Class and object type relations
class Foo {
foo() { return 'foo' }
}
const foo: Foo = new Foo() // Foo is used as interface
const applyMixins = <T, M>(target: T, mixin: M) => {
// typeof target refers to own class type — a function with constuctor signature
}
@antongolub
antongolub / applyMixinsFixed.ts
Last active January 19, 2020 19:07
Apply mixins as a sub-class
export const applyMixinsFixed = <T extends IConstructable, U extends IConstructable[]>(target: T, ...mixins: U) => {
class Mixed extends target {
constructor(...args: any[]) {
super(...args)
mergeDescriptors(this, ...mixins.map(M => new M(...args)))
}
}
@antongolub
antongolub / applyMixins.ts
Last active January 19, 2020 19:06
Mixin example from TS docs
// https://www.typescriptlang.org/docs/handbook/mixins.html#mixin-sample
function applyMixins(derivedCtor: any, baseCtors: any[]) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
Object.defineProperty(derivedCtor.prototype, name, Object.getOwnPropertyDescriptor(baseCtor.prototype, name));
});
});
}