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 ADDED
@@ -0,0 +1,3 @@
1
+ {
2
+ "presets": ["env"]
3
+ }
package/.eslintignore ADDED
@@ -0,0 +1,9 @@
1
+ # don't ever lint node_modules
2
+ node_modules
3
+ # don't lint build output (make sure it's set to your correct build folder name)
4
+ dist
5
+ # don't lint nyc coverage output
6
+ coverage
7
+
8
+ test
9
+ .eslintrc.js
@@ -0,0 +1,12 @@
1
+ # These are supported funding model platforms
2
+
3
+ github: mesqueeb
4
+ patreon: # Replace with a single Patreon username
5
+ open_collective: # Replace with a single Open Collective username
6
+ ko_fi: # Replace with a single Ko-fi username
7
+ tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8
+ community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9
+ liberapay: # Replace with a single Liberapay username
10
+ issuehunt: # Replace with a single IssueHunt username
11
+ otechie: # Replace with a single Otechie username
12
+ custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
package/.prettierrc ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "printWidth": 100,
3
+ "tabWidth": 2,
4
+ "singleQuote": true,
5
+ "trailingComma": "es5",
6
+ "semi": false,
7
+ "bracketSpacing": true,
8
+ "quoteProps": "consistent"
9
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "editor.formatOnSave": true,
3
+ "editor.defaultFormatter": "esbenp.prettier-vscode",
4
+ "editor.tabSize": 2, // make sure this is the same as .prettierrc
5
+ "editor.insertSpaces": true,
6
+ "files.insertFinalNewline": true,
7
+ "files.trimFinalNewlines": true,
8
+ "files.trimTrailingWhitespace": true
9
+ }
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Luca Ban - Mesqueeb
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,272 @@
1
+ # is What? 🙉
2
+
3
+ Very simple & small JS type check functions. It's fully TypeScript supported!
4
+
5
+ ```
6
+ npm i is-what
7
+ ```
8
+
9
+ Or for deno available at: `"deno.land/x/is_what"`
10
+
11
+ ## Motivation
12
+
13
+ I built is-what because the existing solutions were all too complex or too poorly built.
14
+
15
+ I was looking for:
16
+
17
+ - A simple way to check any kind of type (including non-primitives)
18
+ - Be able to check if an object is a plain object `{}` or a special object (like a class instance) ‼️
19
+ - Let TypeScript automatically know what type a value is when checking
20
+
21
+ And that's exactly what `is-what` is! (what a great wordplay 😃)
22
+
23
+ ## Usage
24
+
25
+ is-what is really easy to use, and most functions work just like you'd expect.
26
+
27
+ ```js
28
+ // import functions you want to use like so:
29
+ import { isString, isDate, isPlainObject } from 'is-what'
30
+ ```
31
+
32
+ 1. First I'll go over the simple functions available. Only `isNumber` and `isDate` have special treatment.
33
+ 2. After that I'll talk about working with Objects (plain objects vs class instances etc.).
34
+ 3. Lastly I'll talk about TypeScript implementation
35
+
36
+ ### Simple type check functions
37
+
38
+ ```js
39
+ // basics
40
+ isBoolean(true) // true
41
+ isBoolean(false) // true
42
+ isUndefined(undefined) // true
43
+ isNull(null) // true
44
+
45
+ // strings
46
+ isString('') // true
47
+ isEmptyString('') // true
48
+ isFullString('') // false
49
+
50
+ // numbers
51
+ isNumber(0) // true
52
+ isNumber('0') // false
53
+ isNumber(NaN) // false *
54
+ isPositiveNumber(1) // true
55
+ isNegativeNumber(-1) // true
56
+ // * see below for special NaN use cases!
57
+
58
+ // arrays
59
+ isArray([]) // true
60
+ isEmptyArray([]) // true
61
+ isFullArray([1]) // true
62
+
63
+ // objects
64
+ isPlainObject({}) // true *
65
+ isEmptyObject({}) // true
66
+ isFullObject({ a: 1 }) // true
67
+ // * see below for special object (& class instance) use cases!
68
+
69
+ // functions
70
+ isFunction(function () {}) // true
71
+ isFunction(() => {}) // true
72
+
73
+ // dates
74
+ isDate(new Date()) // true
75
+ isDate(new Date('invalid date')) // false
76
+
77
+ // maps & sets
78
+ isMap(new Map()) // true
79
+ isSet(new Set()) // true
80
+ isWeakMap(new WeakMap()) // true
81
+ isWeakSet(new WeakSet()) // true
82
+
83
+ // others
84
+ isRegExp(/\s/gi) // true
85
+ isSymbol(Symbol()) // true
86
+ isBlob(new Blob()) // true
87
+ isFile(new File([''], '', { type: 'text/html' })) // true
88
+ isError(new Error('')) // true
89
+ isPromise(new Promise((resolve) => {})) // true
90
+
91
+ // primitives
92
+ isPrimitive('') // true
93
+ // true for any of: boolean, null, undefined, number, string, symbol
94
+ ```
95
+
96
+ ### Let's talk about NaN
97
+
98
+ `isNaN` is a built-in JS Function but it really makes no sense:
99
+
100
+ ```js
101
+ // 1)
102
+ typeof NaN === 'number' // true
103
+ // 🤔 ("not a number" is a "number"...)
104
+
105
+ // 2)
106
+ isNaN('1') // false
107
+ // 🤔 the string '1' is not-"not a number"... so it's a number??
108
+
109
+ // 3)
110
+ isNaN('one') // true
111
+ // 🤔 'one' is NaN but `NaN === 'one'` is false...
112
+ ```
113
+
114
+ With is-what the way we treat NaN makes a little bit more sense:
115
+
116
+ ```js
117
+ import { isNumber, isNaNValue } from 'is-what'
118
+
119
+ // 1)
120
+ isNumber(NaN) // false!
121
+ // let's not treat NaN as a number
122
+
123
+ // 2)
124
+ isNaNValue('1') // false
125
+ // if it's not NaN, it's not NaN!!
126
+
127
+ // 3)
128
+ isNaNValue('one') // false
129
+ // if it's not NaN, it's not NaN!!
130
+
131
+ isNaNValue(NaN) // true
132
+ ```
133
+
134
+ ### isPlainObject vs isAnyObject
135
+
136
+ Checking for a JavaScript object can be really difficult. In JavaScript you can create classes that will behave just like JavaScript objects but might have completely different prototypes. With is-what I went for this classification:
137
+
138
+ - `isPlainObject` will only return `true` on plain JavaScript objects and not on classes or others
139
+ - `isAnyObject` will be more loose and return `true` on regular objects, classes, etc.
140
+
141
+ ```js
142
+ // define a plain object
143
+ const plainObject = { hello: 'I am a good old object.' }
144
+
145
+ // define a special object
146
+ class SpecialObject {
147
+ constructor(somethingSpecial) {
148
+ this.speciality = somethingSpecial
149
+ }
150
+ }
151
+ const specialObject = new SpecialObject('I am a special object! I am a class instance!!!')
152
+
153
+ // check the plain object
154
+ isPlainObject(plainObject) // returns true
155
+ isAnyObject(plainObject) // returns true
156
+ getType(plainObject) // returns 'Object'
157
+
158
+ // check the special object
159
+ isPlainObject(specialObject) // returns false !!!!!!!!!
160
+ isAnyObject(specialObject) // returns true
161
+ getType(specialObject) // returns 'Object'
162
+ ```
163
+
164
+ > Please note that `isPlainObject` will only return `true` for normal plain JavaScript objects.
165
+
166
+ ### Getting and checking for specific types
167
+
168
+ You can check for specific types with `getType` and `isType`:
169
+
170
+ ```js
171
+ import { getType, isType } from 'is-what'
172
+
173
+ getType('') // returns 'String'
174
+ // pass a Type as second param:
175
+ isType('', String) // returns true
176
+ ```
177
+
178
+ ## TypeScript
179
+
180
+ is-what makes TypeScript know the type during if statements. This means that a check returns the type of the payload for TypeScript users.
181
+
182
+ ```ts
183
+ function isNumber(payload: any): payload is number {
184
+ // return boolean
185
+ }
186
+ // As you can see above, all functions return a boolean for JavaScript, but pass the payload type to TypeScript.
187
+
188
+ // usage example:
189
+ function fn(payload: string | number): number {
190
+ if (isNumber(payload)) {
191
+ // ↑ TypeScript already knows payload is a number here!
192
+ return payload
193
+ }
194
+ return 0
195
+ }
196
+ ```
197
+
198
+ `isPlainObject` and `isAnyObject` with TypeScript will declare the payload to be an object type with any props:
199
+
200
+ ```ts
201
+ function isPlainObject(payload: any): payload is { [key: string]: any }
202
+ function isAnyObject(payload: any): payload is { [key: string]: any }
203
+ // The reason to return `{[key: string]: any}` is to be able to do
204
+ if (isPlainObject(payload) && payload.id) return payload.id
205
+ // if isPlainObject() would return `payload is object` then it would give an error at `payload.id`
206
+ ```
207
+
208
+ ### isObjectLike
209
+
210
+ If you want more control over what kind of interface/type is casted when checking for objects.
211
+
212
+ To cast to a specific type while checking for `isAnyObject`, can use `isObjectLike<T>`:
213
+
214
+ ```ts
215
+ import { isObjectLike } from 'is-what'
216
+
217
+ const payload = { name: 'Mesqueeb' } // current type: `{ name: string }`
218
+
219
+ // Without casting:
220
+ if (isAnyObject(payload)) {
221
+ // in here `payload` is casted to: `Record<string | number | symbol, any>`
222
+ // WE LOOSE THE TYPE!
223
+ }
224
+
225
+ // With casting:
226
+ // you can pass a specific type for TS that will be casted when the function returns
227
+ if (isObjectLike<{ name: string }>(payload)) {
228
+ // in here `payload` is casted to: `{ name: string }`
229
+ }
230
+ ```
231
+
232
+ Please note: this library will not actually check the shape of the object, you need to do that yourself.
233
+
234
+ `isObjectLike<T>` works like this under the hood:
235
+
236
+ ```ts
237
+ function isObjectLike<T extends object>(payload: any): payload is T {
238
+ return isAnyObject(payload)
239
+ }
240
+ ```
241
+
242
+ ## Meet the family
243
+
244
+ - [is-what 🙉](https://github.com/mesqueeb/is-what)
245
+ - [merge-anything 🥡](https://github.com/mesqueeb/merge-anything)
246
+ - [filter-anything ⚔️](https://github.com/mesqueeb/filter-anything)
247
+ - [find-and-replace-anything 🎣](https://github.com/mesqueeb/find-and-replace-anything)
248
+ - [compare-anything 🛰](https://github.com/mesqueeb/compare-anything)
249
+ - [copy-anything 🎭](https://github.com/mesqueeb/copy-anything)
250
+ - [flatten-anything 🏏](https://github.com/mesqueeb/flatten-anything)
251
+
252
+ ## Source code
253
+
254
+ It's litterally just these functions:
255
+
256
+ ```js
257
+ function getType(payload) {
258
+ return Object.prototype.toString.call(payload).slice(8, -1)
259
+ }
260
+ function isUndefined(payload) {
261
+ return getType(payload) === 'Undefined'
262
+ }
263
+ function isString(payload) {
264
+ return getType(payload) === 'String'
265
+ }
266
+ function isAnyObject(payload) {
267
+ return getType(payload) === 'Object'
268
+ }
269
+ // etc...
270
+ ```
271
+
272
+ See the full source code [here](https://github.com/mesqueeb/is-what/blob/master/src/index.ts).
package/build.js ADDED
@@ -0,0 +1,40 @@
1
+ /* eslint-disable */
2
+
3
+ // npm i -D rollup rollup-plugin-typescript2 typescript
4
+ import typescript from 'rollup-plugin-typescript2'
5
+
6
+ // ------------------------------------------------------------------------------------------
7
+ // formats
8
+ // ------------------------------------------------------------------------------------------
9
+ // amd – Asynchronous Module Definition, used with module loaders like RequireJS
10
+ // cjs – CommonJS, suitable for Node and Browserify/Webpack
11
+ // esm – Keep the bundle as an ES module file
12
+ // iife – A self-executing function, suitable for inclusion as a <script> tag. (If you want to create a bundle for your application, you probably want to use this, because it leads to smaller file sizes.)
13
+ // umd – Universal Module Definition, works as amd, cjs and iife all in one
14
+ // system – Native format of the SystemJS loader
15
+
16
+ // ------------------------------------------------------------------------------------------
17
+ // setup
18
+ // ------------------------------------------------------------------------------------------
19
+ const pkg = require('./package.json')
20
+ const name = pkg.name
21
+ const className = name.replace(/(^\w|-\w)/g, (c) => c.replace('-', '').toUpperCase())
22
+
23
+ export default [
24
+ {
25
+ input: 'src/index.ts',
26
+ output: [
27
+ {
28
+ file: 'dist/index.js',
29
+ format: 'esm',
30
+ sourcemap: false,
31
+ name: className,
32
+ exports: 'named',
33
+ },
34
+ ],
35
+ plugins: [
36
+ typescript({ useTsconfigDeclarationDir: true, tsconfigOverride: { exclude: ['test/**/*'] } }),
37
+ ],
38
+ external: Object.keys(pkg.dependencies || []),
39
+ },
40
+ ]