Skip to content

Instantly share code, notes, and snippets.

@miguel-leon
Last active October 16, 2018 22:34
Show Gist options
  • Save miguel-leon/886e220806bac2c5e2e541d63ac12b62 to your computer and use it in GitHub Desktop.
Save miguel-leon/886e220806bac2c5e2e541d63ac12b62 to your computer and use it in GitHub Desktop.
Auto typed actions to use with stores
export interface Action {
readonly type: string;
}
export class AutoTypedAction implements Action {
static pretty = true;
static getName(obj: Object) {
const name = obj && obj.constructor.name;
return name && AutoTypedAction.pretty ? splitWords(name) : name;
}
@LazyGetter(true)
@NonConfigurable()
get type() {
console.log('generating static type for', this.constructor.name);
return AutoTypedAction.getName(this);
}
}
export class AutoTypedActionWithOrigininator extends AutoTypedAction {
private originator: Object;
originatedBy(originator: Object) {
this.originator = originator;
return this;
}
@LazyGetter()
@NonConfigurable()
get type() {
console.log('generating instance type for', this.constructor.name);
return `[${AutoTypedAction.getName(this.originator)}] ${AutoTypedAction.getName(this)}`;
}
}
export function LazyGetter(setPrototype = false, valueConfigurable = false): MethodDecorator {
return (target: any, key: PropertyKey, descriptor: PropertyDescriptor): void => {
const originalGetter = descriptor.get;
const isStatic = typeof (target) === 'function';
descriptor.get = function () {
const value = originalGetter.apply(this, arguments);
const newDescriptor: PropertyDescriptor = {
configurable: valueConfigurable,
enumerable: descriptor.enumerable,
value
};
if (isStatic || (setPrototype && this.constructor.prototype === target)) {
if (descriptor.configurable) {
Object.defineProperty(target, key, newDescriptor);
}
} else if (setPrototype) {
Object.defineProperty(this.constructor.prototype, key, newDescriptor);
} else if (this !== target && this !== this.constructor.prototype) {
Object.defineProperty(this, key, newDescriptor);
}
return value;
};
};
}
export function NonConfigurable(): MethodDecorator {
return (target: any, key: PropertyKey, descriptor: PropertyDescriptor): void => {
descriptor.configurable = false;
};
}
export function splitWords(str: string) {
return str.replace(/([a-z]|[A-Z]+)([A-Z]+$|[A-Z])/g, "$1 $2");
}
class DataRequestedASAP extends AutoTypedAction/*WithOrigininator*/ {
}
class ILoveUSAComponent {
constructor() {
const act = new DataRequestedASAP()/*.originatedBy(this)*/;
console.log(act);
}
}
new ILoveUSAComponent();
const act = new DataRequestedASAP();
console.log(act);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment