Create a gist now

Instantly share code, notes, and snippets.

@nanto /Emittable.ts
Last active Aug 19, 2016

An emitter (observer pattern) implementation to mixin, written in TypeScript.
// An emitter implementation to mixin.
//
// This file is in the public domain.
//
// Usage:
//
// import Emittable from "...";
//
// class MyEmitter implements Emittable {
// on = Emittable.on;
// off = Emittable.off;
// emit = Emittable.emit;
// }
//
// let emitter = new MyEmitter;
// emitter.on('foo', () => { console.log('emitted!'); });
// emitter.emit('foo');
interface Listener {
(...args: any[]): void;
}
interface EmitMethod {
(type: string, ...args: any[]): void;
}
interface InternalEmitMethod extends EmitMethod {
listenersMap: { [type: string]: Listener[] };
}
interface Emittable {
on(type: string, listener: Listener): void;
off(type: string, listener: Listener): void;
emit: EmitMethod;
}
let Emittable: Emittable = {
on(type: string, listener: Listener): void {
let listenersMap = (<InternalEmitMethod>this.emit).listenersMap;
let listeners = listenersMap[type] || (listenersMap[type] = []);
if (listeners.indexOf(listener) >= 0) return;
listeners.push(listener);
},
off(type: string, listener: Listener): void {
let listeners = (<InternalEmitMethod>this.emit).listenersMap[type];
if (!listeners) return;
let index = listeners.indexOf(listener);
if (index < 0) return;
listeners.splice(index, 1);
},
get emit(): EmitMethod {
let emit = <InternalEmitMethod>function (type: string, ...args: any[]): void {
let listeners = emit.listenersMap[type];
if (!listeners) return;
for (let listener of listeners.concat()) {
listener.apply(null, args);
}
}
emit.listenersMap = {};
return emit;
},
};
export default Emittable;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment