Created
November 1, 2021 06:57
-
-
Save aztack/2ff06894fe061ecd851200901bc1f5ae to your computer and use it in GitHub Desktop.
delegate.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class EventEmitter { | |
on(event: string, callback: () => void) { | |
console.log(`EventEmitter#on`, this.constructor.name); | |
} | |
emit(event: string) { | |
console.log(`EventEmitter#emit`, this.constructor.name); | |
} | |
} | |
class Win { | |
x:number = 41; | |
y:number = 42; | |
moveTo(x:number,y:number) { | |
console.log(`Win#moveTo ${this.x}, ${this.y}`, this.constructor.name); | |
} | |
showDevTools() { | |
console.log(`Win#showDevTools`, this.constructor.name); | |
} | |
closeDevTools() { | |
console.log(`Win#closeDevTools`, this.constructor.name); | |
} | |
close() { | |
console.log(`Win#close`, this.constructor.name); | |
}; | |
} | |
class NwWindow { | |
private win: Win = new Win(); | |
openDevTools() { | |
console.log(`Win#openDevTools`, this.constructor.name); | |
return this.win.showDevTools(); | |
} | |
} | |
// here is the key that make ts understand the inheritance and make code suggestion work as expected | |
interface NwWindow extends Omit<Win, 'showDevTools'>, EventEmitter {} | |
// delegate() make prototype chain work as expected in runtime | |
delegate<NwWindow>(NwWindow, [Win, EventEmitter], 'win'); | |
function delegate<T extends {[key: string]: any}>(derivedCtor: any, constructors: any[], propName: string) { | |
constructors.forEach((inherited) => { | |
Object.getOwnPropertyNames(inherited.prototype).forEach((name) => { | |
const desc = Object.getOwnPropertyDescriptor(inherited.prototype, name); | |
if (desc && name !== 'constructor') { | |
console.log(`Delegating ${name}`); | |
const original = desc.value as Function; | |
desc.value = function (...args: any) { | |
const ptr = this as T; | |
const prop = ptr[propName]; | |
return original.apply(prop, args); | |
}; | |
Object.defineProperty(derivedCtor.prototype, name, desc); | |
} | |
}); | |
}); | |
} | |
const w = new NwWindow(); | |
console.log(w); | |
w.openDevTools(); | |
w.closeDevTools(); | |
w.on('a', console.log); | |
console.log(w); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment