typescriptkit
Version:
Basic functionality for TypeScript projects
108 lines (97 loc) • 4.07 kB
text/typescript
/**
* 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 */