export function isString(value: any): boolean { return typeof value === "string" || value instanceof String; } export function isNumber(value: any): boolean { return typeof value === "number" || value instanceof Number; } export function isFunction(value: any): boolean { if (!value) { return false; } return typeof value === "function"; } export function isUndefined(value: any): boolean { return typeof value === "undefined"; } export function isDefined(value: any): boolean { return typeof value !== "undefined"; } export function isNullOrUndefined(value: any): boolean { return (typeof value === "undefined") || (value === null); } export function verifyCallback(value: any) { if (value && !isFunction(value)) { throw new TypeError("Callback must be a valid function."); } } var classInfosMap = new Map(); var funcNameRegex = /function (.{1,})\(/; export function getClass(object: Object): string { return getClassInfo(object).name; } export function getClassInfo(object: Object): ClassInfo { var constructor = object.constructor; var result = classInfosMap.get(constructor); if (!result) { result = new ClassInfo(constructor); classInfosMap.set(constructor, result); } return result; } export function getBaseClasses(object): Array { var result = []; var info = getClassInfo(object); while (info) { result.push(info.name); info = info.baseClassInfo; } return result; } export class ClassInfo { private _typeCosntructor: Function; private _name: string; private _baseClassInfo: ClassInfo; constructor(typeCosntructor: Function) { this._typeCosntructor = typeCosntructor; } get name(): string { if (!this._name) { var results = (funcNameRegex).exec(this._typeCosntructor.toString()); this._name = (results && results.length > 1) ? results[1] : ""; } return this._name; } get baseClassInfo(): ClassInfo { if (isUndefined(this._baseClassInfo)) { this._baseClassInfo = ClassInfo._getBase(this); // While extending some classes for platform specific versions results in duplicate class types in hierarchy. if (this._baseClassInfo && this._baseClassInfo.name === this.name) { this._baseClassInfo = ClassInfo._getBase(this._baseClassInfo); } } return this._baseClassInfo; } private static _getBase(info: ClassInfo): ClassInfo { var result = null; var constructorProto = info._typeCosntructor.prototype; if (constructorProto.__proto__) { result = getClassInfo(constructorProto.__proto__); } return result; } }