UNPKG

typescriptkit

Version:

Basic functionality for TypeScript projects

108 lines (97 loc) 4.07 kB
/** * Helper Utility for objects and instances */ export class ObjectExtensions { /** * Check whether an object is null or undefined * @param object The object to check. */ public static isNullOrUndefined(object: any): boolean { if (!!!object) return true; // This doesn't always work if (object === null) return true; if (object === undefined) return true; return false; } /** * Get all methods attached to an object * @param object The object to check. */ public static getAllMethods<TClass extends object>(object: TClass): Array<Function> { if (this.isNullOrUndefined(object)) throw new ReferenceError('Cannot get methods from an undefined object'); // Credit where credit is due: http://stackoverflow.com/a/35033472/2319865 let props = []; do { const methodList = Object.getOwnPropertyNames(object) .concat((<any>Object).getOwnPropertySymbols(object).map(s => s.toString())) .sort() .filter((p, i, arr) => typeof object[p] === 'function' && // Only the methods p !== 'constructor' && // Not the constructor (i === 0 || p !== arr[i - 1]) && // Not overriding in this prototype props.indexOf(p) === -1 // Not overridden in a child ) .map(methodName => object[methodName]); props = props.concat(methodList); object = Object.getPrototypeOf(object); // Walk-up the prototype chain } while ( !ObjectExtensions.isNullOrUndefined(object) && // Not the the Object prototype methods (hasOwnProperty, etc...) !ObjectExtensions.isNullOrUndefined(Object.getPrototypeOf(object)) ); return props; } /* Todo: Don't know how to test this */ /** * Get the propertyDecorator for this object * @param object The object to check. * @param propertyName The name of the property the decorator is attached to. * @param descriptorName The name of the descript value where the decorator is attached to. */ public static getPropertyDecorator<TDecorator extends Object>( object: Object, propertyName: string, descriptorName: string): TDecorator { if (!object.hasOwnProperty(propertyName)) return null; let descriptor: PropertyDescriptor = Object.getOwnPropertyDescriptor(object, propertyName); if (ObjectExtensions.isNullOrUndefined(descriptor) || ObjectExtensions.isNullOrUndefined(descriptor.value)) return null; return descriptor.value[descriptorName]; } } /* istanbul ignore start */ /** * Interface to allow extension code completion */ export interface Object { /** * Check whether an object is null or undefined */ isNullOrUndefined(): boolean; /** * Get all methods attached to an object */ getAllMethods<TClass extends Object>(): Array<Function>; /** * Get the propertyDecorator for this object * @param propertyName The name of the property the decorator is attached to. * @param descriptorName The name of the descript value where the decorator is attached to. */ getPropertyDecorator<TDecorator extends Object>( propertyName: string, descriptorName: string): TDecorator; } export default ObjectExtensions; /* istanbul ignore next */ /** * Apply extensions to the Object interface */ // tslint:disable-next-line:no-unused-expression !function applyObjectExtensions(): void { Object.prototype['isNullOrUndefined'] = () => ObjectExtensions.isNullOrUndefined(this); Object.prototype['getAllMethods'] = () => ObjectExtensions.getAllMethods(this); Object.prototype['getPropertyDecorator'] = (propertyName, descriptorName) => ObjectExtensions.getPropertyDecorator(this, propertyName, descriptorName); }(); /* istanbul ignore end */