is-what 4.0.0 → 4.1.3

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # is What? 🙉
2
2
 
3
+ <a href="https://www.npmjs.com/package/is-what"><img src="https://img.shields.io/npm/v/is-what.svg" alt="Total Downloads"></a>
4
+ <a href="https://www.npmjs.com/package/is-what"><img src="https://img.shields.io/npm/dw/is-what.svg" alt="Latest Stable Version"></a>
5
+
3
6
  Very simple & small JS type check functions. It's fully TypeScript supported!
4
7
 
5
8
  ```
@@ -36,6 +39,12 @@ import { isString, isDate, isPlainObject } from 'is-what'
36
39
  ### Simple type check functions
37
40
 
38
41
  ```js
42
+ // basics
43
+ isBoolean(true) // true
44
+ isBoolean(false) // true
45
+ isUndefined(undefined) // true
46
+ isNull(null) // true
47
+
39
48
  // strings
40
49
  isString('') // true
41
50
  isEmptyString('') // true
@@ -43,38 +52,86 @@ isFullString('') // false
43
52
 
44
53
  // numbers
45
54
  isNumber(0) // true
46
- isNumber(NaN) // false
55
+ isNumber('0') // false
56
+ isNumber(NaN) // false *
57
+ isPositiveNumber(1) // true
58
+ isNegativeNumber(-1) // true
59
+ // * see below for special NaN use cases!
60
+
61
+ // arrays
62
+ isArray([]) // true
63
+ isEmptyArray([]) // true
64
+ isFullArray([1]) // true
65
+
66
+ // objects
67
+ isPlainObject({}) // true *
68
+ isEmptyObject({}) // true
69
+ isFullObject({ a: 1 }) // true
70
+ // * see below for special object (& class instance) use cases!
71
+
72
+ // functions
73
+ isFunction(function () {}) // true
74
+ isFunction(() => {}) // true
47
75
 
48
76
  // dates
49
77
  isDate(new Date()) // true
50
78
  isDate(new Date('invalid date')) // false
51
79
 
80
+ // maps & sets
81
+ isMap(new Map()) // true
82
+ isSet(new Set()) // true
83
+ isWeakMap(new WeakMap()) // true
84
+ isWeakSet(new WeakSet()) // true
85
+
52
86
  // others
53
- isBoolean(false) // true
54
- isFunction(function () {}) // true
55
- isArray([]) // true
56
- isUndefined(undefined) // true
57
- isNull(null) // true
58
87
  isRegExp(/\s/gi) // true
59
88
  isSymbol(Symbol()) // true
60
89
  isBlob(new Blob()) // true
61
90
  isFile(new File([''], '', { type: 'text/html' })) // true
91
+ isError(new Error('')) // true
92
+ isPromise(new Promise((resolve) => {})) // true
62
93
 
63
94
  // primitives
64
95
  isPrimitive('') // true
65
96
  // true for any of: boolean, null, undefined, number, string, symbol
66
97
  ```
67
98
 
68
- ### Getting and checking for specific types
99
+ ### Let's talk about NaN
69
100
 
70
- You can check for specific types with `getType` and `isType`:
101
+ `isNaN` is a built-in JS Function but it really makes no sense:
71
102
 
72
103
  ```js
73
- import { getType, isType } from 'is-what'
104
+ // 1)
105
+ typeof NaN === 'number' // true
106
+ // 🤔 ("not a number" is a "number"...)
74
107
 
75
- getType('') // returns 'String'
76
- // pass a Type as second param:
77
- isType('', String) // returns true
108
+ // 2)
109
+ isNaN('1') // false
110
+ // 🤔 the string '1' is not-"not a number"... so it's a number??
111
+
112
+ // 3)
113
+ isNaN('one') // true
114
+ // 🤔 'one' is NaN but `NaN === 'one'` is false...
115
+ ```
116
+
117
+ With is-what the way we treat NaN makes a little bit more sense:
118
+
119
+ ```js
120
+ import { isNumber, isNaNValue } from 'is-what'
121
+
122
+ // 1)
123
+ isNumber(NaN) // false!
124
+ // let's not treat NaN as a number
125
+
126
+ // 2)
127
+ isNaNValue('1') // false
128
+ // if it's not NaN, it's not NaN!!
129
+
130
+ // 3)
131
+ isNaNValue('one') // false
132
+ // if it's not NaN, it's not NaN!!
133
+
134
+ isNaNValue(NaN) // true
78
135
  ```
79
136
 
80
137
  ### isPlainObject vs isAnyObject
@@ -109,6 +166,18 @@ getType(specialObject) // returns 'Object'
109
166
 
110
167
  > Please note that `isPlainObject` will only return `true` for normal plain JavaScript objects.
111
168
 
169
+ ### Getting and checking for specific types
170
+
171
+ You can check for specific types with `getType` and `isType`:
172
+
173
+ ```js
174
+ import { getType, isType } from 'is-what'
175
+
176
+ getType('') // returns 'String'
177
+ // pass a Type as second param:
178
+ isType('', String) // returns true
179
+ ```
180
+
112
181
  ## TypeScript
113
182
 
114
183
  is-what makes TypeScript know the type during if statements. This means that a check returns the type of the payload for TypeScript users.
@@ -141,16 +210,30 @@ if (isPlainObject(payload) && payload.id) return payload.id
141
210
 
142
211
  ### isObjectLike
143
212
 
144
- If you want more control over which kind of objects are allowed you can use `isObjectLike<T>`:
213
+ If you want more control over what kind of interface/type is casted when checking for objects.
214
+
215
+ To cast to a specific type while checking for `isAnyObject`, can use `isObjectLike<T>`:
145
216
 
146
217
  ```ts
147
218
  import { isObjectLike } from 'is-what'
148
- // usage examples:
149
- isObjectLike<{ specificKey: string }>(payload)
150
- isObjectLike<object>(payload)
151
- // you can pass a specific type for TS to check on.
219
+
220
+ const payload = { name: 'Mesqueeb' } // current type: `{ name: string }`
221
+
222
+ // Without casting:
223
+ if (isAnyObject(payload)) {
224
+ // in here `payload` is casted to: `Record<string | number | symbol, any>`
225
+ // WE LOOSE THE TYPE!
226
+ }
227
+
228
+ // With casting:
229
+ // you can pass a specific type for TS that will be casted when the function returns
230
+ if (isObjectLike<{ name: string }>(payload)) {
231
+ // in here `payload` is casted to: `{ name: string }`
232
+ }
152
233
  ```
153
234
 
235
+ Please note: this library will not actually check the shape of the object, you need to do that yourself.
236
+
154
237
  `isObjectLike<T>` works like this under the hood:
155
238
 
156
239
  ```ts
package/dist/index.cjs ADDED
@@ -0,0 +1,382 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ /**
6
+ * Returns the object type of the given payload
7
+ *
8
+ * @param {*} payload
9
+ * @returns {string}
10
+ */
11
+ function getType(payload) {
12
+ return Object.prototype.toString.call(payload).slice(8, -1);
13
+ }
14
+ /**
15
+ * Returns whether the payload is undefined
16
+ *
17
+ * @param {*} payload
18
+ * @returns {payload is undefined}
19
+ */
20
+ function isUndefined(payload) {
21
+ return getType(payload) === 'Undefined';
22
+ }
23
+ /**
24
+ * Returns whether the payload is null
25
+ *
26
+ * @param {*} payload
27
+ * @returns {payload is null}
28
+ */
29
+ function isNull(payload) {
30
+ return getType(payload) === 'Null';
31
+ }
32
+ /**
33
+ * Returns whether the payload is a plain JavaScript object (excluding special classes or objects with other prototypes)
34
+ *
35
+ * @param {*} payload
36
+ * @returns {payload is PlainObject}
37
+ */
38
+ function isPlainObject(payload) {
39
+ if (getType(payload) !== 'Object')
40
+ return false;
41
+ return payload.constructor === Object && Object.getPrototypeOf(payload) === Object.prototype;
42
+ }
43
+ /**
44
+ * Returns whether the payload is a plain JavaScript object (excluding special classes or objects with other prototypes)
45
+ *
46
+ * @param {*} payload
47
+ * @returns {payload is PlainObject}
48
+ */
49
+ function isObject(payload) {
50
+ return isPlainObject(payload);
51
+ }
52
+ /**
53
+ * Returns whether the payload is a an empty object (excluding special classes or objects with other prototypes)
54
+ *
55
+ * @param {*} payload
56
+ * @returns {payload is { [K in any]: never }}
57
+ */
58
+ function isEmptyObject(payload) {
59
+ return isPlainObject(payload) && Object.keys(payload).length === 0;
60
+ }
61
+ /**
62
+ * Returns whether the payload is a an empty object (excluding special classes or objects with other prototypes)
63
+ *
64
+ * @param {*} payload
65
+ * @returns {payload is PlainObject}
66
+ */
67
+ function isFullObject(payload) {
68
+ return isPlainObject(payload) && Object.keys(payload).length > 0;
69
+ }
70
+ /**
71
+ * Returns whether the payload is an any kind of object (including special classes or objects with different prototypes)
72
+ *
73
+ * @param {*} payload
74
+ * @returns {payload is PlainObject}
75
+ */
76
+ function isAnyObject(payload) {
77
+ return getType(payload) === 'Object';
78
+ }
79
+ /**
80
+ * Returns whether the payload is an object like a type passed in < >
81
+ *
82
+ * Usage: isObjectLike<{id: any}>(payload) // will make sure it's an object and has an `id` prop.
83
+ *
84
+ * @template T this must be passed in < >
85
+ * @param {*} payload
86
+ * @returns {payload is T}
87
+ */
88
+ function isObjectLike(payload) {
89
+ return isAnyObject(payload);
90
+ }
91
+ /**
92
+ * Returns whether the payload is a function (regular or async)
93
+ *
94
+ * @param {*} payload
95
+ * @returns {payload is AnyFunction}
96
+ */
97
+ function isFunction(payload) {
98
+ return typeof payload === 'function';
99
+ }
100
+ /**
101
+ * Returns whether the payload is an array
102
+ *
103
+ * @param {any} payload
104
+ * @returns {payload is any[]}
105
+ */
106
+ function isArray(payload) {
107
+ return getType(payload) === 'Array';
108
+ }
109
+ /**
110
+ * Returns whether the payload is a an array with at least 1 item
111
+ *
112
+ * @param {*} payload
113
+ * @returns {payload is any[]}
114
+ */
115
+ function isFullArray(payload) {
116
+ return isArray(payload) && payload.length > 0;
117
+ }
118
+ /**
119
+ * Returns whether the payload is a an empty array
120
+ *
121
+ * @param {*} payload
122
+ * @returns {payload is []}
123
+ */
124
+ function isEmptyArray(payload) {
125
+ return isArray(payload) && payload.length === 0;
126
+ }
127
+ /**
128
+ * Returns whether the payload is a string
129
+ *
130
+ * @param {*} payload
131
+ * @returns {payload is string}
132
+ */
133
+ function isString(payload) {
134
+ return getType(payload) === 'String';
135
+ }
136
+ /**
137
+ * Returns whether the payload is a string, BUT returns false for ''
138
+ *
139
+ * @param {*} payload
140
+ * @returns {payload is string}
141
+ */
142
+ function isFullString(payload) {
143
+ return isString(payload) && payload !== '';
144
+ }
145
+ /**
146
+ * Returns whether the payload is ''
147
+ *
148
+ * @param {*} payload
149
+ * @returns {payload is string}
150
+ */
151
+ function isEmptyString(payload) {
152
+ return payload === '';
153
+ }
154
+ /**
155
+ * Returns whether the payload is a number (but not NaN)
156
+ *
157
+ * This will return `false` for `NaN`!!
158
+ *
159
+ * @param {*} payload
160
+ * @returns {payload is number}
161
+ */
162
+ function isNumber(payload) {
163
+ return getType(payload) === 'Number' && !isNaN(payload);
164
+ }
165
+ /**
166
+ * Returns whether the payload is a positive number (but not 0)
167
+ *
168
+ * @param {*} payload
169
+ * @returns {payload is number}
170
+ */
171
+ function isPositiveNumber(payload) {
172
+ return isNumber(payload) && payload > 0;
173
+ }
174
+ /**
175
+ * Returns whether the payload is a negative number (but not 0)
176
+ *
177
+ * @param {*} payload
178
+ * @returns {payload is number}
179
+ */
180
+ function isNegativeNumber(payload) {
181
+ return isNumber(payload) && payload < 0;
182
+ }
183
+ /**
184
+ * Returns whether the payload is a boolean
185
+ *
186
+ * @param {*} payload
187
+ * @returns {payload is boolean}
188
+ */
189
+ function isBoolean(payload) {
190
+ return getType(payload) === 'Boolean';
191
+ }
192
+ /**
193
+ * Returns whether the payload is a regular expression (RegExp)
194
+ *
195
+ * @param {*} payload
196
+ * @returns {payload is RegExp}
197
+ */
198
+ function isRegExp(payload) {
199
+ return getType(payload) === 'RegExp';
200
+ }
201
+ /**
202
+ * Returns whether the payload is a Map
203
+ *
204
+ * @param {*} payload
205
+ * @returns {payload is Map<any, any>}
206
+ */
207
+ function isMap(payload) {
208
+ return getType(payload) === 'Map';
209
+ }
210
+ /**
211
+ * Returns whether the payload is a WeakMap
212
+ *
213
+ * @param {*} payload
214
+ * @returns {payload is WeakMap<any, any>}
215
+ */
216
+ function isWeakMap(payload) {
217
+ return getType(payload) === 'WeakMap';
218
+ }
219
+ /**
220
+ * Returns whether the payload is a Set
221
+ *
222
+ * @param {*} payload
223
+ * @returns {payload is Set<any>}
224
+ */
225
+ function isSet(payload) {
226
+ return getType(payload) === 'Set';
227
+ }
228
+ /**
229
+ * Returns whether the payload is a WeakSet
230
+ *
231
+ * @param {*} payload
232
+ * @returns {payload is WeakSet<any>}
233
+ */
234
+ function isWeakSet(payload) {
235
+ return getType(payload) === 'WeakSet';
236
+ }
237
+ /**
238
+ * Returns whether the payload is a Symbol
239
+ *
240
+ * @param {*} payload
241
+ * @returns {payload is symbol}
242
+ */
243
+ function isSymbol(payload) {
244
+ return getType(payload) === 'Symbol';
245
+ }
246
+ /**
247
+ * Returns whether the payload is a Date, and that the date is valid
248
+ *
249
+ * @param {*} payload
250
+ * @returns {payload is Date}
251
+ */
252
+ function isDate(payload) {
253
+ return getType(payload) === 'Date' && !isNaN(payload);
254
+ }
255
+ /**
256
+ * Returns whether the payload is a Blob
257
+ *
258
+ * @param {*} payload
259
+ * @returns {payload is Blob}
260
+ */
261
+ function isBlob(payload) {
262
+ return getType(payload) === 'Blob';
263
+ }
264
+ /**
265
+ * Returns whether the payload is a File
266
+ *
267
+ * @param {*} payload
268
+ * @returns {payload is File}
269
+ */
270
+ function isFile(payload) {
271
+ return getType(payload) === 'File';
272
+ }
273
+ /**
274
+ * Returns whether the payload is a Promise
275
+ *
276
+ * @param {*} payload
277
+ * @returns {payload is Promise<any>}
278
+ */
279
+ function isPromise(payload) {
280
+ return getType(payload) === 'Promise';
281
+ }
282
+ /**
283
+ * Returns whether the payload is an Error
284
+ *
285
+ * @param {*} payload
286
+ * @returns {payload is Error}
287
+ */
288
+ function isError(payload) {
289
+ return getType(payload) === 'Error';
290
+ }
291
+ /**
292
+ * Returns whether the payload is literally the value `NaN` (it's `NaN` and also a `number`)
293
+ *
294
+ * @param {*} payload
295
+ * @returns {payload is typeof NaN}
296
+ */
297
+ function isNaNValue(payload) {
298
+ return getType(payload) === 'Number' && isNaN(payload);
299
+ }
300
+ /**
301
+ * Returns whether the payload is a primitive type (eg. Boolean | Null | Undefined | Number | String | Symbol)
302
+ *
303
+ * @param {*} payload
304
+ * @returns {(payload is boolean | null | undefined | number | string | symbol)}
305
+ */
306
+ function isPrimitive(payload) {
307
+ return (isBoolean(payload) ||
308
+ isNull(payload) ||
309
+ isUndefined(payload) ||
310
+ isNumber(payload) ||
311
+ isString(payload) ||
312
+ isSymbol(payload));
313
+ }
314
+ /**
315
+ * Returns true whether the payload is null or undefined
316
+ *
317
+ * @param {*} payload
318
+ * @returns {(payload is null | undefined)}
319
+ */
320
+ const isNullOrUndefined = isOneOf(isNull, isUndefined);
321
+ function isOneOf(a, b, c, d, e) {
322
+ return (value) => a(value) || b(value) || (!!c && c(value)) || (!!d && d(value)) || (!!e && e(value));
323
+ }
324
+ /**
325
+ * Does a generic check to check that the given payload is of a given type.
326
+ * In cases like Number, it will return true for NaN as NaN is a Number (thanks javascript!);
327
+ * It will, however, differentiate between object and null
328
+ *
329
+ * @template T
330
+ * @param {*} payload
331
+ * @param {T} type
332
+ * @throws {TypeError} Will throw type error if type is an invalid type
333
+ * @returns {payload is T}
334
+ */
335
+ function isType(payload, type) {
336
+ if (!(type instanceof Function)) {
337
+ throw new TypeError('Type must be a function');
338
+ }
339
+ if (!Object.prototype.hasOwnProperty.call(type, 'prototype')) {
340
+ throw new TypeError('Type is not a class');
341
+ }
342
+ // Classes usually have names (as functions usually have names)
343
+ const name = type.name;
344
+ return getType(payload) === name || Boolean(payload && payload.constructor === type);
345
+ }
346
+
347
+ exports.getType = getType;
348
+ exports.isAnyObject = isAnyObject;
349
+ exports.isArray = isArray;
350
+ exports.isBlob = isBlob;
351
+ exports.isBoolean = isBoolean;
352
+ exports.isDate = isDate;
353
+ exports.isEmptyArray = isEmptyArray;
354
+ exports.isEmptyObject = isEmptyObject;
355
+ exports.isEmptyString = isEmptyString;
356
+ exports.isError = isError;
357
+ exports.isFile = isFile;
358
+ exports.isFullArray = isFullArray;
359
+ exports.isFullObject = isFullObject;
360
+ exports.isFullString = isFullString;
361
+ exports.isFunction = isFunction;
362
+ exports.isMap = isMap;
363
+ exports.isNaNValue = isNaNValue;
364
+ exports.isNegativeNumber = isNegativeNumber;
365
+ exports.isNull = isNull;
366
+ exports.isNullOrUndefined = isNullOrUndefined;
367
+ exports.isNumber = isNumber;
368
+ exports.isObject = isObject;
369
+ exports.isObjectLike = isObjectLike;
370
+ exports.isOneOf = isOneOf;
371
+ exports.isPlainObject = isPlainObject;
372
+ exports.isPositiveNumber = isPositiveNumber;
373
+ exports.isPrimitive = isPrimitive;
374
+ exports.isPromise = isPromise;
375
+ exports.isRegExp = isRegExp;
376
+ exports.isSet = isSet;
377
+ exports.isString = isString;
378
+ exports.isSymbol = isSymbol;
379
+ exports.isType = isType;
380
+ exports.isUndefined = isUndefined;
381
+ exports.isWeakMap = isWeakMap;
382
+ exports.isWeakSet = isWeakSet;
@@ -158,6 +158,24 @@ function isEmptyString(payload) {
158
158
  function isNumber(payload) {
159
159
  return getType(payload) === 'Number' && !isNaN(payload);
160
160
  }
161
+ /**
162
+ * Returns whether the payload is a positive number (but not 0)
163
+ *
164
+ * @param {*} payload
165
+ * @returns {payload is number}
166
+ */
167
+ function isPositiveNumber(payload) {
168
+ return isNumber(payload) && payload > 0;
169
+ }
170
+ /**
171
+ * Returns whether the payload is a negative number (but not 0)
172
+ *
173
+ * @param {*} payload
174
+ * @returns {payload is number}
175
+ */
176
+ function isNegativeNumber(payload) {
177
+ return isNumber(payload) && payload < 0;
178
+ }
161
179
  /**
162
180
  * Returns whether the payload is a boolean
163
181
  *
@@ -322,4 +340,4 @@ function isType(payload, type) {
322
340
  return getType(payload) === name || Boolean(payload && payload.constructor === type);
323
341
  }
324
342
 
325
- export { getType, isAnyObject, isArray, isBlob, isBoolean, isDate, isEmptyArray, isEmptyObject, isEmptyString, isError, isFile, isFullArray, isFullObject, isFullString, isFunction, isMap, isNaNValue, isNull, isNullOrUndefined, isNumber, isObject, isObjectLike, isOneOf, isPlainObject, isPrimitive, isPromise, isRegExp, isSet, isString, isSymbol, isType, isUndefined, isWeakMap, isWeakSet };
343
+ export { getType, isAnyObject, isArray, isBlob, isBoolean, isDate, isEmptyArray, isEmptyObject, isEmptyString, isError, isFile, isFullArray, isFullObject, isFullString, isFunction, isMap, isNaNValue, isNegativeNumber, isNull, isNullOrUndefined, isNumber, isObject, isObjectLike, isOneOf, isPlainObject, isPositiveNumber, isPrimitive, isPromise, isRegExp, isSet, isString, isSymbol, isType, isUndefined, isWeakMap, isWeakSet };
@@ -129,6 +129,20 @@ export declare function isEmptyString(payload: any): payload is string;
129
129
  * @returns {payload is number}
130
130
  */
131
131
  export declare function isNumber(payload: any): payload is number;
132
+ /**
133
+ * Returns whether the payload is a positive number (but not 0)
134
+ *
135
+ * @param {*} payload
136
+ * @returns {payload is number}
137
+ */
138
+ export declare function isPositiveNumber(payload: any): payload is number;
139
+ /**
140
+ * Returns whether the payload is a negative number (but not 0)
141
+ *
142
+ * @param {*} payload
143
+ * @returns {payload is number}
144
+ */
145
+ export declare function isNegativeNumber(payload: any): payload is number;
132
146
  /**
133
147
  * Returns whether the payload is a boolean
134
148
  *