-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Expand file tree
/
Copy pathtypes.ts
More file actions
134 lines (105 loc) · 3.28 KB
/
Copy pathtypes.ts
File metadata and controls
134 lines (105 loc) · 3.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
export function isString(value: any): value is string {
return typeof value === 'string' || value instanceof String;
}
export function isNumber(value: any): value is number {
return typeof value === 'number' || value instanceof Number;
}
export function isBoolean(value: any): value is boolean {
return typeof value === 'boolean' || value instanceof Boolean;
}
export function isFunction(value: any): value is Function {
if (!value) {
return false;
}
return typeof value === 'function';
}
export function isObject(value: any): value is Record<string,any> {
if (!value) {
return false;
}
return typeof value === 'object';
}
export function isUndefined(value: any): value is undefined {
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.');
}
}
export function numberHasDecimals(value: number): boolean {
return !(value % 1 === 0);
}
export function numberIs64Bit(value: number): boolean {
return value < -Math.pow(2, 31) + 1 || value > Math.pow(2, 31) - 1;
}
const classInfosMap = new Map<Function, ClassInfo>();
// ES3-5 type classes are "function blah()", new ES6+ classes can be "class blah"
const funcNameRegex = /(?:function|class)\s+(\w+).*/;
export function getClass(object: Object): string {
return getClassInfo(object).name;
}
export function getClassInfo(object: Object): ClassInfo {
const constructor = object.constructor;
let result = classInfosMap.get(constructor);
if (!result) {
result = new ClassInfo(constructor);
classInfosMap.set(constructor, result);
}
return result;
}
export function getBaseClasses(object): Array<string> {
const result = [];
let info = getClassInfo(object);
while (info) {
result.push(info.name);
info = info.baseClassInfo;
}
return result;
}
export class ClassInfo {
private _typeConstructor: Function;
private _name: string;
private _baseClassInfo: ClassInfo;
constructor(typeConstructor: Function) {
this._typeConstructor = typeConstructor;
}
get name(): string {
if (!this._name) {
if (this._typeConstructor.name) {
this._name = this._typeConstructor.name;
} else {
const results = funcNameRegex.exec(this._typeConstructor.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 {
let result = null;
const constructorProto = info._typeConstructor.prototype;
if (constructorProto.__proto__) {
result = getClassInfo(constructorProto.__proto__);
}
return result;
}
}
export function toUIString(obj): string {
return isNullOrUndefined(obj) ? '' : obj + '';
}