source: trip-planner-front/node_modules/is-what/src/index.ts

Last change on this file was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 10.1 KB
Line 
1export type AnyFunction = (...args: any[]) => any
2export type AnyAsyncFunction = (...args: any[]) => Promise<any>
3export type AnyClass = new (...args: any[]) => any
4export type PlainObject = Record<string | number | symbol, any>
5
6type TypeGuard<A, B extends A> = (payload: A) => payload is B
7
8/**
9 * Returns the object type of the given payload
10 *
11 * @param {*} payload
12 * @returns {string}
13 */
14export function getType(payload: any): string {
15 return Object.prototype.toString.call(payload).slice(8, -1)
16}
17
18/**
19 * Returns whether the payload is undefined
20 *
21 * @param {*} payload
22 * @returns {payload is undefined}
23 */
24export function isUndefined(payload: any): payload is undefined {
25 return getType(payload) === 'Undefined'
26}
27
28/**
29 * Returns whether the payload is null
30 *
31 * @param {*} payload
32 * @returns {payload is null}
33 */
34export function isNull(payload: any): payload is null {
35 return getType(payload) === 'Null'
36}
37
38/**
39 * Returns whether the payload is a plain JavaScript object (excluding special classes or objects with other prototypes)
40 *
41 * @param {*} payload
42 * @returns {payload is PlainObject}
43 */
44export function isPlainObject(payload: any): payload is PlainObject {
45 if (getType(payload) !== 'Object') return false
46 return payload.constructor === Object && Object.getPrototypeOf(payload) === Object.prototype
47}
48
49/**
50 * Returns whether the payload is a plain JavaScript object (excluding special classes or objects with other prototypes)
51 *
52 * @param {*} payload
53 * @returns {payload is PlainObject}
54 */
55export function isObject(payload: any): payload is PlainObject {
56 return isPlainObject(payload)
57}
58
59/**
60 * Returns whether the payload is a an empty object (excluding special classes or objects with other prototypes)
61 *
62 * @param {*} payload
63 * @returns {payload is { [K in any]: never }}
64 */
65export function isEmptyObject(payload: any): payload is { [K in any]: never } {
66 return isPlainObject(payload) && Object.keys(payload).length === 0
67}
68
69/**
70 * Returns whether the payload is a an empty object (excluding special classes or objects with other prototypes)
71 *
72 * @param {*} payload
73 * @returns {payload is PlainObject}
74 */
75export function isFullObject(payload: any): payload is PlainObject {
76 return isPlainObject(payload) && Object.keys(payload).length > 0
77}
78
79/**
80 * Returns whether the payload is an any kind of object (including special classes or objects with different prototypes)
81 *
82 * @param {*} payload
83 * @returns {payload is PlainObject}
84 */
85export function isAnyObject(payload: any): payload is PlainObject {
86 return getType(payload) === 'Object'
87}
88
89/**
90 * Returns whether the payload is an object like a type passed in < >
91 *
92 * Usage: isObjectLike<{id: any}>(payload) // will make sure it's an object and has an `id` prop.
93 *
94 * @template T this must be passed in < >
95 * @param {*} payload
96 * @returns {payload is T}
97 */
98export function isObjectLike<T extends PlainObject>(payload: any): payload is T {
99 return isAnyObject(payload)
100}
101
102/**
103 * Returns whether the payload is a function (regular or async)
104 *
105 * @param {*} payload
106 * @returns {payload is AnyFunction}
107 */
108export function isFunction(payload: any): payload is AnyFunction {
109 return typeof payload === 'function'
110}
111
112/**
113 * Returns whether the payload is an array
114 *
115 * @param {any} payload
116 * @returns {payload is any[]}
117 */
118export function isArray(payload: any): payload is any[] {
119 return getType(payload) === 'Array'
120}
121
122/**
123 * Returns whether the payload is a an array with at least 1 item
124 *
125 * @param {*} payload
126 * @returns {payload is any[]}
127 */
128export function isFullArray(payload: any): payload is any[] {
129 return isArray(payload) && payload.length > 0
130}
131
132/**
133 * Returns whether the payload is a an empty array
134 *
135 * @param {*} payload
136 * @returns {payload is []}
137 */
138export function isEmptyArray(payload: any): payload is [] {
139 return isArray(payload) && payload.length === 0
140}
141
142/**
143 * Returns whether the payload is a string
144 *
145 * @param {*} payload
146 * @returns {payload is string}
147 */
148export function isString(payload: any): payload is string {
149 return getType(payload) === 'String'
150}
151
152/**
153 * Returns whether the payload is a string, BUT returns false for ''
154 *
155 * @param {*} payload
156 * @returns {payload is string}
157 */
158export function isFullString(payload: any): payload is string {
159 return isString(payload) && payload !== ''
160}
161
162/**
163 * Returns whether the payload is ''
164 *
165 * @param {*} payload
166 * @returns {payload is string}
167 */
168export function isEmptyString(payload: any): payload is string {
169 return payload === ''
170}
171
172/**
173 * Returns whether the payload is a number (but not NaN)
174 *
175 * This will return `false` for `NaN`!!
176 *
177 * @param {*} payload
178 * @returns {payload is number}
179 */
180export function isNumber(payload: any): payload is number {
181 return getType(payload) === 'Number' && !isNaN(payload)
182}
183
184/**
185 * Returns whether the payload is a boolean
186 *
187 * @param {*} payload
188 * @returns {payload is boolean}
189 */
190export function isBoolean(payload: any): payload is boolean {
191 return getType(payload) === 'Boolean'
192}
193
194/**
195 * Returns whether the payload is a regular expression (RegExp)
196 *
197 * @param {*} payload
198 * @returns {payload is RegExp}
199 */
200export function isRegExp(payload: any): payload is RegExp {
201 return getType(payload) === 'RegExp'
202}
203
204/**
205 * Returns whether the payload is a Map
206 *
207 * @param {*} payload
208 * @returns {payload is Map<any, any>}
209 */
210export function isMap(payload: any): payload is Map<any, any> {
211 return getType(payload) === 'Map'
212}
213
214/**
215 * Returns whether the payload is a WeakMap
216 *
217 * @param {*} payload
218 * @returns {payload is WeakMap<any, any>}
219 */
220export function isWeakMap(payload: any): payload is WeakMap<any, any> {
221 return getType(payload) === 'WeakMap'
222}
223
224/**
225 * Returns whether the payload is a Set
226 *
227 * @param {*} payload
228 * @returns {payload is Set<any>}
229 */
230export function isSet(payload: any): payload is Set<any> {
231 return getType(payload) === 'Set'
232}
233
234/**
235 * Returns whether the payload is a WeakSet
236 *
237 * @param {*} payload
238 * @returns {payload is WeakSet<any>}
239 */
240export function isWeakSet(payload: any): payload is WeakSet<any> {
241 return getType(payload) === 'WeakSet'
242}
243
244/**
245 * Returns whether the payload is a Symbol
246 *
247 * @param {*} payload
248 * @returns {payload is symbol}
249 */
250export function isSymbol(payload: any): payload is symbol {
251 return getType(payload) === 'Symbol'
252}
253
254/**
255 * Returns whether the payload is a Date, and that the date is valid
256 *
257 * @param {*} payload
258 * @returns {payload is Date}
259 */
260export function isDate(payload: any): payload is Date {
261 return getType(payload) === 'Date' && !isNaN(payload)
262}
263
264/**
265 * Returns whether the payload is a Blob
266 *
267 * @param {*} payload
268 * @returns {payload is Blob}
269 */
270export function isBlob(payload: any): payload is Blob {
271 return getType(payload) === 'Blob'
272}
273
274/**
275 * Returns whether the payload is a File
276 *
277 * @param {*} payload
278 * @returns {payload is File}
279 */
280export function isFile(payload: any): payload is File {
281 return getType(payload) === 'File'
282}
283
284/**
285 * Returns whether the payload is a Promise
286 *
287 * @param {*} payload
288 * @returns {payload is Promise<any>}
289 */
290export function isPromise(payload: any): payload is Promise<any> {
291 return getType(payload) === 'Promise'
292}
293
294/**
295 * Returns whether the payload is an Error
296 *
297 * @param {*} payload
298 * @returns {payload is Error}
299 */
300export function isError(payload: any): payload is Error {
301 return getType(payload) === 'Error'
302}
303
304/**
305 * Returns whether the payload is literally the value `NaN` (it's `NaN` and also a `number`)
306 *
307 * @param {*} payload
308 * @returns {payload is typeof NaN}
309 */
310export function isNaNValue(payload: any): payload is typeof NaN {
311 return getType(payload) === 'Number' && isNaN(payload)
312}
313
314/**
315 * Returns whether the payload is a primitive type (eg. Boolean | Null | Undefined | Number | String | Symbol)
316 *
317 * @param {*} payload
318 * @returns {(payload is boolean | null | undefined | number | string | symbol)}
319 */
320export function isPrimitive(
321 payload: any
322): payload is boolean | null | undefined | number | string | symbol {
323 return (
324 isBoolean(payload) ||
325 isNull(payload) ||
326 isUndefined(payload) ||
327 isNumber(payload) ||
328 isString(payload) ||
329 isSymbol(payload)
330 )
331}
332
333/**
334 * Returns true whether the payload is null or undefined
335 *
336 * @param {*} payload
337 * @returns {(payload is null | undefined)}
338 */
339export const isNullOrUndefined = isOneOf(isNull, isUndefined)
340
341export function isOneOf<A, B extends A, C extends A>(
342 a: TypeGuard<A, B>,
343 b: TypeGuard<A, C>
344): TypeGuard<A, B | C>
345export function isOneOf<A, B extends A, C extends A, D extends A>(
346 a: TypeGuard<A, B>,
347 b: TypeGuard<A, C>,
348 c: TypeGuard<A, D>
349): TypeGuard<A, B | C | D>
350export function isOneOf<A, B extends A, C extends A, D extends A, E extends A>(
351 a: TypeGuard<A, B>,
352 b: TypeGuard<A, C>,
353 c: TypeGuard<A, D>,
354 d: TypeGuard<A, E>
355): TypeGuard<A, B | C | D | E>
356export function isOneOf<A, B extends A, C extends A, D extends A, E extends A, F extends A>(
357 a: TypeGuard<A, B>,
358 b: TypeGuard<A, C>,
359 c: TypeGuard<A, D>,
360 d: TypeGuard<A, E>,
361 e: TypeGuard<A, F>
362): TypeGuard<A, B | C | D | E | F>
363export function isOneOf(
364 a: AnyFunction,
365 b: AnyFunction,
366 c?: AnyFunction,
367 d?: AnyFunction,
368 e?: AnyFunction
369): (value: unknown) => boolean {
370 return (value) =>
371 a(value) || b(value) || (!!c && c(value)) || (!!d && d(value)) || (!!e && e(value))
372}
373
374/**
375 * Does a generic check to check that the given payload is of a given type.
376 * In cases like Number, it will return true for NaN as NaN is a Number (thanks javascript!);
377 * It will, however, differentiate between object and null
378 *
379 * @template T
380 * @param {*} payload
381 * @param {T} type
382 * @throws {TypeError} Will throw type error if type is an invalid type
383 * @returns {payload is T}
384 */
385export function isType<T extends AnyFunction | AnyClass>(payload: any, type: T): payload is T {
386 if (!(type instanceof Function)) {
387 throw new TypeError('Type must be a function')
388 }
389 if (!Object.prototype.hasOwnProperty.call(type, 'prototype')) {
390 throw new TypeError('Type is not a class')
391 }
392 // Classes usually have names (as functions usually have names)
393 const name: string | undefined | null = (type as any).name
394 return getType(payload) === name || Boolean(payload && payload.constructor === type)
395}
Note: See TracBrowser for help on using the repository browser.