@exadel/esl
Version:
Exadel Smart Library (ESL) is the lightweight custom elements library that provide a set of super-flexible components
44 lines (43 loc) • 1.9 kB
JavaScript
import { getPropertyDescriptor } from '../misc/object/utils';
/**
* Common TS decorator to apply decorator function
* (like {@link debounce}, {@link throttle}, {@link rafDecorator})
* to the class method
* @param decorator - function decorator, should accept decorated method as first argument
* @param args - additional arguments to pass into `decorator`
*/
export function decorate(decorator, ...args) {
return function (target, propertyKey, descriptor) {
if (!descriptor || typeof descriptor.value !== 'function') {
throw new TypeError('Only class methods can be decorated');
}
const originalFn = descriptor.value;
return descriptor = {
enumerable: descriptor.enumerable,
configurable: true,
get: function getBound() {
// Skip own properties
const proto = Object.getPrototypeOf(this);
// Find the closest descriptor for property
const desc = getPropertyDescriptor(proto, propertyKey);
// Return original function in case of prototype or super call
if (!desc || desc.get !== getBound)
return originalFn;
// Create a new decorated instance of function
const decoratedFn = decorator(originalFn.bind(this), ...args);
// Copy original function own keys
Object.assign(decoratedFn, originalFn);
// Defines own property with the decorated instance
return this[propertyKey] = decoratedFn;
},
set(value) {
Object.defineProperty(this, propertyKey, {
value,
writable: true,
configurable: true,
enumerable: descriptor.enumerable
});
}
};
};
}