is-what 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc +3 -0
- package/.eslintignore +9 -0
- package/.github/FUNDING.yml +12 -0
- package/.prettierrc +9 -0
- package/.vscode/settings.json +9 -0
- package/LICENSE +21 -0
- package/README.md +272 -0
- package/build.js +40 -0
- package/dist/index.js +343 -0
- package/package.json +105 -0
- package/src/index.ts +415 -0
- package/test/ava.ts +419 -0
- package/tsconfig.json +15 -0
- package/types/index.d.ts +267 -0
package/src/index.ts
ADDED
@@ -0,0 +1,415 @@
|
|
1
|
+
export type AnyFunction = (...args: any[]) => any
|
2
|
+
export type AnyAsyncFunction = (...args: any[]) => Promise<any>
|
3
|
+
export type AnyClass = new (...args: any[]) => any
|
4
|
+
export type PlainObject = Record<string | number | symbol, any>
|
5
|
+
|
6
|
+
type 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
|
+
*/
|
14
|
+
export 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
|
+
*/
|
24
|
+
export 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
|
+
*/
|
34
|
+
export 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
|
+
*/
|
44
|
+
export 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
|
+
*/
|
55
|
+
export 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
|
+
*/
|
65
|
+
export 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
|
+
*/
|
75
|
+
export 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
|
+
*/
|
85
|
+
export 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
|
+
*/
|
98
|
+
export 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
|
+
*/
|
108
|
+
export 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
|
+
*/
|
118
|
+
export 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
|
+
*/
|
128
|
+
export 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
|
+
*/
|
138
|
+
export 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
|
+
*/
|
148
|
+
export 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
|
+
*/
|
158
|
+
export 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
|
+
*/
|
168
|
+
export 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
|
+
*/
|
180
|
+
export function isNumber(payload: any): payload is number {
|
181
|
+
return getType(payload) === 'Number' && !isNaN(payload)
|
182
|
+
}
|
183
|
+
|
184
|
+
/**
|
185
|
+
* Returns whether the payload is a positive number (but not 0)
|
186
|
+
*
|
187
|
+
* @param {*} payload
|
188
|
+
* @returns {payload is number}
|
189
|
+
*/
|
190
|
+
export function isPositiveNumber(payload: any): payload is number {
|
191
|
+
return isNumber(payload) && payload > 0
|
192
|
+
}
|
193
|
+
|
194
|
+
/**
|
195
|
+
* Returns whether the payload is a negative number (but not 0)
|
196
|
+
*
|
197
|
+
* @param {*} payload
|
198
|
+
* @returns {payload is number}
|
199
|
+
*/
|
200
|
+
export function isNegativeNumber(payload: any): payload is number {
|
201
|
+
return isNumber(payload) && payload < 0
|
202
|
+
}
|
203
|
+
|
204
|
+
/**
|
205
|
+
* Returns whether the payload is a boolean
|
206
|
+
*
|
207
|
+
* @param {*} payload
|
208
|
+
* @returns {payload is boolean}
|
209
|
+
*/
|
210
|
+
export function isBoolean(payload: any): payload is boolean {
|
211
|
+
return getType(payload) === 'Boolean'
|
212
|
+
}
|
213
|
+
|
214
|
+
/**
|
215
|
+
* Returns whether the payload is a regular expression (RegExp)
|
216
|
+
*
|
217
|
+
* @param {*} payload
|
218
|
+
* @returns {payload is RegExp}
|
219
|
+
*/
|
220
|
+
export function isRegExp(payload: any): payload is RegExp {
|
221
|
+
return getType(payload) === 'RegExp'
|
222
|
+
}
|
223
|
+
|
224
|
+
/**
|
225
|
+
* Returns whether the payload is a Map
|
226
|
+
*
|
227
|
+
* @param {*} payload
|
228
|
+
* @returns {payload is Map<any, any>}
|
229
|
+
*/
|
230
|
+
export function isMap(payload: any): payload is Map<any, any> {
|
231
|
+
return getType(payload) === 'Map'
|
232
|
+
}
|
233
|
+
|
234
|
+
/**
|
235
|
+
* Returns whether the payload is a WeakMap
|
236
|
+
*
|
237
|
+
* @param {*} payload
|
238
|
+
* @returns {payload is WeakMap<any, any>}
|
239
|
+
*/
|
240
|
+
export function isWeakMap(payload: any): payload is WeakMap<any, any> {
|
241
|
+
return getType(payload) === 'WeakMap'
|
242
|
+
}
|
243
|
+
|
244
|
+
/**
|
245
|
+
* Returns whether the payload is a Set
|
246
|
+
*
|
247
|
+
* @param {*} payload
|
248
|
+
* @returns {payload is Set<any>}
|
249
|
+
*/
|
250
|
+
export function isSet(payload: any): payload is Set<any> {
|
251
|
+
return getType(payload) === 'Set'
|
252
|
+
}
|
253
|
+
|
254
|
+
/**
|
255
|
+
* Returns whether the payload is a WeakSet
|
256
|
+
*
|
257
|
+
* @param {*} payload
|
258
|
+
* @returns {payload is WeakSet<any>}
|
259
|
+
*/
|
260
|
+
export function isWeakSet(payload: any): payload is WeakSet<any> {
|
261
|
+
return getType(payload) === 'WeakSet'
|
262
|
+
}
|
263
|
+
|
264
|
+
/**
|
265
|
+
* Returns whether the payload is a Symbol
|
266
|
+
*
|
267
|
+
* @param {*} payload
|
268
|
+
* @returns {payload is symbol}
|
269
|
+
*/
|
270
|
+
export function isSymbol(payload: any): payload is symbol {
|
271
|
+
return getType(payload) === 'Symbol'
|
272
|
+
}
|
273
|
+
|
274
|
+
/**
|
275
|
+
* Returns whether the payload is a Date, and that the date is valid
|
276
|
+
*
|
277
|
+
* @param {*} payload
|
278
|
+
* @returns {payload is Date}
|
279
|
+
*/
|
280
|
+
export function isDate(payload: any): payload is Date {
|
281
|
+
return getType(payload) === 'Date' && !isNaN(payload)
|
282
|
+
}
|
283
|
+
|
284
|
+
/**
|
285
|
+
* Returns whether the payload is a Blob
|
286
|
+
*
|
287
|
+
* @param {*} payload
|
288
|
+
* @returns {payload is Blob}
|
289
|
+
*/
|
290
|
+
export function isBlob(payload: any): payload is Blob {
|
291
|
+
return getType(payload) === 'Blob'
|
292
|
+
}
|
293
|
+
|
294
|
+
/**
|
295
|
+
* Returns whether the payload is a File
|
296
|
+
*
|
297
|
+
* @param {*} payload
|
298
|
+
* @returns {payload is File}
|
299
|
+
*/
|
300
|
+
export function isFile(payload: any): payload is File {
|
301
|
+
return getType(payload) === 'File'
|
302
|
+
}
|
303
|
+
|
304
|
+
/**
|
305
|
+
* Returns whether the payload is a Promise
|
306
|
+
*
|
307
|
+
* @param {*} payload
|
308
|
+
* @returns {payload is Promise<any>}
|
309
|
+
*/
|
310
|
+
export function isPromise(payload: any): payload is Promise<any> {
|
311
|
+
return getType(payload) === 'Promise'
|
312
|
+
}
|
313
|
+
|
314
|
+
/**
|
315
|
+
* Returns whether the payload is an Error
|
316
|
+
*
|
317
|
+
* @param {*} payload
|
318
|
+
* @returns {payload is Error}
|
319
|
+
*/
|
320
|
+
export function isError(payload: any): payload is Error {
|
321
|
+
return getType(payload) === 'Error'
|
322
|
+
}
|
323
|
+
|
324
|
+
/**
|
325
|
+
* Returns whether the payload is literally the value `NaN` (it's `NaN` and also a `number`)
|
326
|
+
*
|
327
|
+
* @param {*} payload
|
328
|
+
* @returns {payload is typeof NaN}
|
329
|
+
*/
|
330
|
+
export function isNaNValue(payload: any): payload is typeof NaN {
|
331
|
+
return getType(payload) === 'Number' && isNaN(payload)
|
332
|
+
}
|
333
|
+
|
334
|
+
/**
|
335
|
+
* Returns whether the payload is a primitive type (eg. Boolean | Null | Undefined | Number | String | Symbol)
|
336
|
+
*
|
337
|
+
* @param {*} payload
|
338
|
+
* @returns {(payload is boolean | null | undefined | number | string | symbol)}
|
339
|
+
*/
|
340
|
+
export function isPrimitive(
|
341
|
+
payload: any
|
342
|
+
): payload is boolean | null | undefined | number | string | symbol {
|
343
|
+
return (
|
344
|
+
isBoolean(payload) ||
|
345
|
+
isNull(payload) ||
|
346
|
+
isUndefined(payload) ||
|
347
|
+
isNumber(payload) ||
|
348
|
+
isString(payload) ||
|
349
|
+
isSymbol(payload)
|
350
|
+
)
|
351
|
+
}
|
352
|
+
|
353
|
+
/**
|
354
|
+
* Returns true whether the payload is null or undefined
|
355
|
+
*
|
356
|
+
* @param {*} payload
|
357
|
+
* @returns {(payload is null | undefined)}
|
358
|
+
*/
|
359
|
+
export const isNullOrUndefined = isOneOf(isNull, isUndefined)
|
360
|
+
|
361
|
+
export function isOneOf<A, B extends A, C extends A>(
|
362
|
+
a: TypeGuard<A, B>,
|
363
|
+
b: TypeGuard<A, C>
|
364
|
+
): TypeGuard<A, B | C>
|
365
|
+
export function isOneOf<A, B extends A, C extends A, D extends A>(
|
366
|
+
a: TypeGuard<A, B>,
|
367
|
+
b: TypeGuard<A, C>,
|
368
|
+
c: TypeGuard<A, D>
|
369
|
+
): TypeGuard<A, B | C | D>
|
370
|
+
export function isOneOf<A, B extends A, C extends A, D extends A, E extends A>(
|
371
|
+
a: TypeGuard<A, B>,
|
372
|
+
b: TypeGuard<A, C>,
|
373
|
+
c: TypeGuard<A, D>,
|
374
|
+
d: TypeGuard<A, E>
|
375
|
+
): TypeGuard<A, B | C | D | E>
|
376
|
+
export function isOneOf<A, B extends A, C extends A, D extends A, E extends A, F extends A>(
|
377
|
+
a: TypeGuard<A, B>,
|
378
|
+
b: TypeGuard<A, C>,
|
379
|
+
c: TypeGuard<A, D>,
|
380
|
+
d: TypeGuard<A, E>,
|
381
|
+
e: TypeGuard<A, F>
|
382
|
+
): TypeGuard<A, B | C | D | E | F>
|
383
|
+
export function isOneOf(
|
384
|
+
a: AnyFunction,
|
385
|
+
b: AnyFunction,
|
386
|
+
c?: AnyFunction,
|
387
|
+
d?: AnyFunction,
|
388
|
+
e?: AnyFunction
|
389
|
+
): (value: unknown) => boolean {
|
390
|
+
return (value) =>
|
391
|
+
a(value) || b(value) || (!!c && c(value)) || (!!d && d(value)) || (!!e && e(value))
|
392
|
+
}
|
393
|
+
|
394
|
+
/**
|
395
|
+
* Does a generic check to check that the given payload is of a given type.
|
396
|
+
* In cases like Number, it will return true for NaN as NaN is a Number (thanks javascript!);
|
397
|
+
* It will, however, differentiate between object and null
|
398
|
+
*
|
399
|
+
* @template T
|
400
|
+
* @param {*} payload
|
401
|
+
* @param {T} type
|
402
|
+
* @throws {TypeError} Will throw type error if type is an invalid type
|
403
|
+
* @returns {payload is T}
|
404
|
+
*/
|
405
|
+
export function isType<T extends AnyFunction | AnyClass>(payload: any, type: T): payload is T {
|
406
|
+
if (!(type instanceof Function)) {
|
407
|
+
throw new TypeError('Type must be a function')
|
408
|
+
}
|
409
|
+
if (!Object.prototype.hasOwnProperty.call(type, 'prototype')) {
|
410
|
+
throw new TypeError('Type is not a class')
|
411
|
+
}
|
412
|
+
// Classes usually have names (as functions usually have names)
|
413
|
+
const name: string | undefined | null = (type as any).name
|
414
|
+
return getType(payload) === name || Boolean(payload && payload.constructor === type)
|
415
|
+
}
|