60d97fb49d654d0f541a2ac4938bbcb5d9a98a4203aa42f43d6b58599181f01a4edb8939b82b9eb556f2035c21a1f18ac53dbf2571a9eabba3f9f2e5ece7a4 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /**
  2. * @returns whether the provided parameter is a JavaScript Array or not.
  3. */
  4. export function isArray(array) {
  5. return Array.isArray(array);
  6. }
  7. /**
  8. * @returns whether the provided parameter is a JavaScript String or not.
  9. */
  10. export function isString(str) {
  11. return (typeof str === 'string');
  12. }
  13. /**
  14. *
  15. * @returns whether the provided parameter is of type `object` but **not**
  16. * `null`, an `array`, a `regexp`, nor a `date`.
  17. */
  18. export function isObject(obj) {
  19. // The method can't do a type cast since there are type (like strings) which
  20. // are subclasses of any put not positvely matched by the function. Hence type
  21. // narrowing results in wrong results.
  22. return typeof obj === 'object'
  23. && obj !== null
  24. && !Array.isArray(obj)
  25. && !(obj instanceof RegExp)
  26. && !(obj instanceof Date);
  27. }
  28. /**
  29. *
  30. * @returns whether the provided parameter is of type `Buffer` or Uint8Array dervived type
  31. */
  32. export function isTypedArray(obj) {
  33. const TypedArray = Object.getPrototypeOf(Uint8Array);
  34. return typeof obj === 'object'
  35. && obj instanceof TypedArray;
  36. }
  37. /**
  38. * In **contrast** to just checking `typeof` this will return `false` for `NaN`.
  39. * @returns whether the provided parameter is a JavaScript Number or not.
  40. */
  41. export function isNumber(obj) {
  42. return (typeof obj === 'number' && !isNaN(obj));
  43. }
  44. /**
  45. * @returns whether the provided parameter is an Iterable, casting to the given generic
  46. */
  47. export function isIterable(obj) {
  48. return !!obj && typeof obj[Symbol.iterator] === 'function';
  49. }
  50. /**
  51. * @returns whether the provided parameter is a JavaScript Boolean or not.
  52. */
  53. export function isBoolean(obj) {
  54. return (obj === true || obj === false);
  55. }
  56. /**
  57. * @returns whether the provided parameter is undefined.
  58. */
  59. export function isUndefined(obj) {
  60. return (typeof obj === 'undefined');
  61. }
  62. /**
  63. * @returns whether the provided parameter is defined.
  64. */
  65. export function isDefined(arg) {
  66. return !isUndefinedOrNull(arg);
  67. }
  68. /**
  69. * @returns whether the provided parameter is undefined or null.
  70. */
  71. export function isUndefinedOrNull(obj) {
  72. return (isUndefined(obj) || obj === null);
  73. }
  74. export function assertType(condition, type) {
  75. if (!condition) {
  76. throw new Error(type ? `Unexpected type, expected '${type}'` : 'Unexpected type');
  77. }
  78. }
  79. /**
  80. * Asserts that the argument passed in is neither undefined nor null.
  81. */
  82. export function assertIsDefined(arg) {
  83. if (isUndefinedOrNull(arg)) {
  84. throw new Error('Assertion Failed: argument is undefined or null');
  85. }
  86. return arg;
  87. }
  88. /**
  89. * @returns whether the provided parameter is a JavaScript Function or not.
  90. */
  91. export function isFunction(obj) {
  92. return (typeof obj === 'function');
  93. }
  94. export function validateConstraints(args, constraints) {
  95. const len = Math.min(args.length, constraints.length);
  96. for (let i = 0; i < len; i++) {
  97. validateConstraint(args[i], constraints[i]);
  98. }
  99. }
  100. export function validateConstraint(arg, constraint) {
  101. if (isString(constraint)) {
  102. if (typeof arg !== constraint) {
  103. throw new Error(`argument does not match constraint: typeof ${constraint}`);
  104. }
  105. }
  106. else if (isFunction(constraint)) {
  107. try {
  108. if (arg instanceof constraint) {
  109. return;
  110. }
  111. }
  112. catch (_a) {
  113. // ignore
  114. }
  115. if (!isUndefinedOrNull(arg) && arg.constructor === constraint) {
  116. return;
  117. }
  118. if (constraint.length === 1 && constraint.call(undefined, arg) === true) {
  119. return;
  120. }
  121. throw new Error(`argument does not match one of these constraints: arg instanceof constraint, arg.constructor === constraint, nor constraint(arg) === true`);
  122. }
  123. }
  124. export function getAllPropertyNames(obj) {
  125. let res = [];
  126. let proto = Object.getPrototypeOf(obj);
  127. while (Object.prototype !== proto) {
  128. res = res.concat(Object.getOwnPropertyNames(proto));
  129. proto = Object.getPrototypeOf(proto);
  130. }
  131. return res;
  132. }
  133. export function getAllMethodNames(obj) {
  134. const methods = [];
  135. for (const prop of getAllPropertyNames(obj)) {
  136. if (typeof obj[prop] === 'function') {
  137. methods.push(prop);
  138. }
  139. }
  140. return methods;
  141. }
  142. export function createProxyObject(methodNames, invoke) {
  143. const createProxyMethod = (method) => {
  144. return function () {
  145. const args = Array.prototype.slice.call(arguments, 0);
  146. return invoke(method, args);
  147. };
  148. };
  149. const result = {};
  150. for (const methodName of methodNames) {
  151. result[methodName] = createProxyMethod(methodName);
  152. }
  153. return result;
  154. }
  155. /**
  156. * Converts null to undefined, passes all other values through.
  157. */
  158. export function withNullAsUndefined(x) {
  159. return x === null ? undefined : x;
  160. }
  161. export function assertNever(value, message = 'Unreachable') {
  162. throw new Error(message);
  163. }