is-kit 1.6.1 → 1.6.3

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/README.md CHANGED
@@ -1,260 +1,295 @@
1
1
  # is-kit
2
2
 
3
3
  <p align="center">
4
- <img src="https://raw.githubusercontent.com/nyaomaru/is-kit/main/docs/public/iskit_image.png" width="600px" align="center" alt="is-kit logo" />
4
+ <img
5
+ src="https://raw.githubusercontent.com/nyaomaru/is-kit/main/docs/public/iskit_image.png"
6
+ width="600"
7
+ alt="is-kit logo"
8
+ />
5
9
  </p>
6
10
 
7
11
  <p align="center">
8
- <a href="https://www.npmjs.com/package/is-kit">
9
- <img src="https://img.shields.io/npm/v/is-kit.svg" alt="npm version">
10
- </a>
11
- <a href="https://jsr.io/@nyaomaru/is-kit">
12
- <img src="https://img.shields.io/jsr/v/@nyaomaru/is-kit" alt="JSR">
13
- </a>
14
- <a href="https://www.npmjs.com/package/is-kit">
15
- <img src="https://img.shields.io/npm/dt/is-kit.svg" alt="npm downloads">
16
- </a>
17
- <a href="https://github.com/nyaomaru/is-kit/blob/main/LICENSE">
18
- <img src="https://img.shields.io/npm/l/is-kit.svg?sanitize=true" alt="License">
19
- </a>
12
+ <a href="https://www.npmjs.com/package/is-kit">
13
+ <img src="https://img.shields.io/npm/v/is-kit.svg" alt="npm version">
14
+ </a>
15
+ <a href="https://jsr.io/@nyaomaru/is-kit">
16
+ <img src="https://img.shields.io/jsr/v/@nyaomaru/is-kit" alt="JSR">
17
+ </a>
18
+ <a href="https://www.npmjs.com/package/is-kit">
19
+ <img src="https://img.shields.io/npm/dt/is-kit.svg" alt="npm downloads">
20
+ </a>
21
+ <a href="https://github.com/nyaomaru/is-kit/blob/main/LICENSE">
22
+ <img src="https://img.shields.io/npm/l/is-kit.svg?sanitize=true" alt="License">
23
+ </a>
20
24
  </p>
21
25
 
22
- Lightweight, zero-dependency toolkit for building `isFoo` style type guards in TypeScript.
23
- Runtime-safe 🛡️, composable 🧩, and ergonomic ✨.
26
+ `is-kit` is a lightweight, zero-dependency toolkit for building reusable TypeScript **type guards**.
24
27
 
25
- [📚 full documentation](https://is-kit-docs.vercel.app/)
28
+ It helps you write small `isFoo` functions, compose them into **richer runtime checks**, and keep **TypeScript narrowing** natural inside regular control flow.
26
29
 
27
- ## Why?
30
+ **Runtime-safe** 🛡️, **composable** 🧩, and **ergonomic** ✨ without asking you to adopt a heavy schema workflow.
28
31
 
29
- Tired of writing the same `isFoo` again and again?
30
- Let `is-kit` do it for you:
32
+ - Build and reuse **typed guards**
33
+ - **Compose guards** with `and`, `or`, `not`, `oneOf`
34
+ - **Validate object** shapes and collections
35
+ - **Parse or assert** `unknown` values without a large schema framework
31
36
 
32
- - Less boilerplate
33
- - Type-safe
34
- - Composable
35
- - Zero-dependency
37
+ [📚 Documentation Site](https://is-kit-docs.vercel.app/)
36
38
 
37
- > Grab a coffee, let `is-kit` do the boring work.
39
+ > Best for **app-internal narrowing, filtering, and reusable guards**.
38
40
 
39
- ## Install
41
+ ## 🤔 Why use `is-kit`?
40
42
 
41
- Node via npm
43
+ Tired of rewriting the same `isFoo` checks again and again?
44
+
45
+ `is-kit` is a good fit when you want to:
46
+
47
+ - **write reusable `isX`** functions instead of one-off inline checks
48
+ - keep runtime validation **lightweight and dependency-free**
49
+ - **narrow values directly** in `if`, `filter`, and other TypeScript control flow
50
+ - **compose validation logic** from small guards instead of large schema objects
51
+
52
+ `is-kit` is probably not the best first choice if you mainly want:
53
+
54
+ - rich, structured validation errors
55
+ - schema-first workflows
56
+ - data transformation pipelines
57
+
58
+ In those cases, a schema validator such as `Zod` may be a better fit. (Of course, you can combine them 🍲)
59
+
60
+ `is-kit` is meant to take the boring part out of writing guards, while still feeling like normal TypeScript.
61
+
62
+ > Grab a coffee ☕ and let `is-kit` handle the repetitive part.
63
+
64
+ ## 📥 Install
42
65
 
43
66
  ```bash
44
67
  pnpm add is-kit
45
68
  # or
46
69
  bun add is-kit
47
70
  # or
48
- npm i is-kit
71
+ npm install is-kit
49
72
  # or
50
73
  yarn add is-kit
51
74
  ```
52
75
 
53
- ESM and CJS builds are provided for npm consumers. Types are bundled.
76
+ ESM and CJS builds are available for npm consumers, and bundled types are included.
54
77
 
55
- ### JSR (TypeScript source)
78
+ ### JSR
56
79
 
57
80
  ```ts
58
- // Deno/Bun/JSR-aware tooling
59
- import { define, and, or } from 'jsr:@nyaomaru/is-kit';
81
+ import { and, define, or } from 'jsr:@nyaomaru/is-kit';
60
82
  ```
61
83
 
62
- ## Quick start
84
+ ## Quick Start
63
85
 
64
- Build `is` functions from tiny, composable pieces:
86
+ Start with a plain object guard and parse an `unknown` value.
65
87
 
66
88
  ```ts
67
- import {
68
- define,
69
- and,
70
- or,
71
- not,
72
- mapOf,
73
- optionalKey,
74
- setOf,
75
- struct,
76
- oneOfValues,
77
- isNumber,
78
- isString,
79
- predicateToRefine
80
- } from 'is-kit';
89
+ import { isNumber, isString, optionalKey, safeParse, struct } from 'is-kit';
81
90
 
82
- // Define small guards
83
- const isShortString = define<string>((v) => isString(v) && v.length <= 3);
84
- const isPositive = and(
85
- isNumber,
86
- predicateToRefine<number>((v) => v > 0)
87
- );
91
+ declare const input: unknown;
88
92
 
89
- // Combine them (or / not)
90
- const isShortOrPositive = or(isShortString, isPositive);
91
- const isOther = not(isShortOrPositive);
92
-
93
- // Define object shapes
94
- const isRole = oneOfValues(['admin', 'member'] as const);
95
- const isTags = setOf(isString);
96
- const isScores = mapOf(isString, isNumber);
97
93
  const isUser = struct({
98
- id: isPositive, // number > 0
99
- name: isString, // string
100
- role: isRole, // 'admin' | 'member'
101
- nickname: optionalKey(isShortString) // key may be absent; when present, string <= 3
94
+ id: isNumber,
95
+ name: isString,
96
+ nickname: optionalKey(isString)
102
97
  });
103
98
 
104
- // Use them
105
- isPositive(3); // true
106
- isShortOrPositive('foo'); // true
107
- isShortOrPositive(false); // false
108
- isOther('x'); // true
109
- isTags(new Set(['new', 'vip'])); // true
110
- isScores(new Map([['math', 98]])); // true
111
-
112
- const maybeUser: unknown = { id: 7, name: 'Rin', role: 'admin' };
113
- if (isUser(maybeUser)) {
114
- // The type is narrowed inside this block
115
- maybeUser.role; // 'admin' | 'member'
116
- maybeUser.nickname?.toUpperCase();
99
+ const result = safeParse(isUser, input);
100
+
101
+ if (result.valid) {
102
+ result.value.id;
103
+ result.value.name;
104
+ result.value.nickname?.toUpperCase();
117
105
  }
118
106
  ```
119
107
 
120
- Use `optionalKey(...)` for key-level optional properties in `struct`.
121
- Use `optional(...)` when the key exists but the value itself may be `undefined`.
122
- Combine them as `optionalKey(optional(guard))` when both are allowed.
108
+ This is the core idea of `is-kit`:
109
+
110
+ 1. Build small guards.
111
+ 2. Compose them.
112
+ 3. Reuse them anywhere TypeScript narrowing matters.
113
+
114
+ ## ⌚ A 30-second Mental Model
115
+
116
+ If you are new to the library, these are the pieces to remember:
117
+
118
+ - `define<T>(fn)` turns a boolean check into a typed guard.
119
+ - `predicateToRefine(fn)` upgrades an existing predicate so it can participate in narrowing chains.
120
+ - `struct({...})` builds an object-shape guard.
121
+ - `safeParse(guard, value)` gives you a small tagged result object.
122
+ - `assert(guard, value)` throws if the value does not match.
123
+
124
+ ## ⚒️ Common Usage
125
+
126
+ ### 1. Create a custom guard
127
+
128
+ Use `define` when you already know the runtime condition you want.
129
+
130
+ ```ts
131
+ import { define, isString } from 'is-kit';
132
+
133
+ const isShortString = define<string>(
134
+ (value) => isString(value) && value.length <= 3
135
+ );
136
+ ```
137
+
138
+ ### 2. Add refinements to an existing guard
139
+
140
+ Use `and` plus `predicateToRefine` when you want a broad guard first and a narrower condition after that.
141
+
142
+ ```ts
143
+ import { and, isNumber, predicateToRefine } from 'is-kit';
144
+
145
+ const isPositiveNumber = and(
146
+ isNumber,
147
+ predicateToRefine<number>((value) => value > 0)
148
+ );
149
+ ```
150
+
151
+ ### 3. Compose multiple guards
152
+
153
+ Use `or` and `oneOf` to combine smaller guards into readable predicates.
154
+
155
+ ```ts
156
+ import { oneOf, or, isBoolean, isNumber, isString } from 'is-kit';
157
+
158
+ const isStringOrNumber = or(isString, isNumber);
159
+ const isScalar = oneOf(isString, isNumber, isBoolean);
160
+ ```
161
+
162
+ Use `not(...)` when you want the complement of an existing guard or refinement.
163
+
164
+ ### 4. Validate object shapes
165
+
166
+ Use `struct` for plain-object payloads. Keys are required by default.
167
+
168
+ ```ts
169
+ import { isNumber, isString, optionalKey, struct } from 'is-kit';
170
+
171
+ const isProfile = struct(
172
+ {
173
+ id: isNumber,
174
+ name: isString,
175
+ bio: optionalKey(isString)
176
+ },
177
+ { exact: true }
178
+ );
179
+ ```
180
+
181
+ `optionalKey(guard)` means the property may be missing.
123
182
 
124
- Composed guards stay reusable:
125
- `isPositive` can be used standalone or as part of a `struct` definition.
183
+ If the property must exist but the value may be `undefined`, use `optional(guard)` instead.
126
184
 
127
- When validating complex shapes, reach for `struct` and collection
128
- combinators like `arrayOf`, `setOf`, `mapOf`, `recordOf`, or `oneOf`.
185
+ ```ts
186
+ import { isString, optional, optionalKey, struct } from 'is-kit';
129
187
 
130
- ### Collection combinators
188
+ const isConfig = struct({
189
+ label: isString,
190
+ subtitle: optional(isString),
191
+ note: optionalKey(optional(isString))
192
+ });
193
+ ```
194
+
195
+ ### 5. Validate arrays, tuples, maps, sets, and records
131
196
 
132
- Use `arrayOf`, `setOf`, `mapOf`, and `recordOf` to validate homogeneous
133
- collections while preserving precise readonly types.
197
+ Collection combinators keep your element guards reusable.
134
198
 
135
199
  ```ts
136
200
  import {
137
201
  arrayOf,
202
+ isNumber,
203
+ isString,
138
204
  mapOf,
139
205
  recordOf,
140
206
  setOf,
141
- isNumber,
142
- isString
207
+ tupleOf
143
208
  } from 'is-kit';
144
209
 
145
210
  const isStringArray = arrayOf(isString);
146
- const isStringSet = setOf(isString);
211
+ const isPoint = tupleOf(isNumber, isNumber);
212
+ const isTagSet = setOf(isString);
147
213
  const isScoreMap = mapOf(isString, isNumber);
148
214
  const isStringRecord = recordOf(isString, isString);
149
-
150
- isStringArray(['a', 'b']); // true
151
- isStringSet(new Set(['a', 'b'])); // true
152
- isScoreMap(new Map([['math', 98]])); // true
153
- isStringRecord({ a: 'x', b: 'y' }); // true
154
215
  ```
155
216
 
156
- ### Primitive guards
217
+ Use `oneOfValues` for unions of literal primitives.
218
+
219
+ ```ts
220
+ import { oneOfValues } from 'is-kit';
221
+
222
+ const isStatus = oneOfValues('draft', 'published', 'archived');
223
+ ```
157
224
 
158
- Built-in primitives: `isString`, `isNumber` (finite), `isBoolean`, `isBigInt`, `isSymbol`, `isUndefined`, `isNull` — and a preset `isPrimitive` for any primitive.
225
+ ### 6. Handle null and undefined explicitly
159
226
 
160
- Numeric helpers are included for common cases: `isInteger`, `isSafeInteger`, `isPositive`, `isNegative`, `isZero`, `isNaN`, `isInfiniteNumber`.
227
+ Use the nullish helpers to say exactly what is allowed.
161
228
 
162
229
  ```ts
163
230
  import {
164
- isPrimitive,
165
- isNumber,
166
- isInteger,
167
- isSafeInteger,
168
- isPositive,
169
- isNegative,
170
- isZero,
171
- isNaN,
172
- isInfiniteNumber
231
+ isString,
232
+ nonNull,
233
+ nullable,
234
+ nullish,
235
+ optional,
236
+ required
173
237
  } from 'is-kit';
174
238
 
175
- // Any primitive
176
- isPrimitive('x'); // true
177
- isPrimitive(123); // true
178
- isPrimitive(NaN); // true (use isNumber for finite only)
179
- isPrimitive({}); // false
180
-
181
- // Numeric helpers
182
- isNumber(10); // true
183
- isInteger(42); // true
184
- isSafeInteger(2 ** 53); // false
185
- isPositive(3); // true
186
- isPositive(0); // false
187
- isNegative(-3); // true
188
- isNegative(-0); // false
189
- isZero(0); // true
190
- isZero(1); // false
191
- isNaN(NaN); // true
192
- isNaN(0); // false
193
- isInfiniteNumber(Infinity); // true
194
- isInfiniteNumber(1); // false
239
+ const isNullableString = nullable(isString);
240
+ const isNullishString = nullish(isString);
241
+ const isOptionalString = optional(isString);
242
+ const isDefinedString = required(optional(isString));
243
+ const isNonNullString = nonNull(nullable(isString));
195
244
  ```
196
245
 
197
- ### Object guards
246
+ ### 7. Parse or assert unknown input
198
247
 
199
- Object/built-in guards cover arrays, dates, maps/sets, and more. Use
200
- `isInstanceOf` when you want a reusable guard from a class constructor.
201
- For content-aware map/set validation, pair `isMap` / `isSet` with `mapOf`
202
- and `setOf`.
248
+ Use `safeParse` when you want a result object, and `assert` when invalid data should stop execution.
203
249
 
204
250
  ```ts
205
- import { isArray, isDate, isInstanceOf } from 'is-kit';
251
+ import { assert, isString, safeParse } from 'is-kit';
206
252
 
207
- class Animal {}
208
- class Dog extends Animal {}
253
+ declare const input: unknown;
209
254
 
210
- const isAnimal = isInstanceOf(Animal);
255
+ const parsed = safeParse(isString, input);
211
256
 
212
- isArray([]); // true
213
- isDate(new Date()); // true
214
- isAnimal(new Dog()); // true
215
- isAnimal({}); // false
216
- ```
217
-
218
- ## Core Ideas
257
+ if (parsed.valid) {
258
+ parsed.value.toUpperCase();
259
+ }
219
260
 
220
- - **Define once**: `define<T>(fn)` turns a plain function into a type guard.
221
- - **Upgrade predicates**: `predicateToRefine(fn)` adds narrowing.
222
- - **Compose freely**: `and`, `or`, `not`, `oneOf`, `arrayOf`, `setOf`, `mapOf`, `struct` …
223
- - **Stay ergonomic**: helpers like `nullable`, `optional`, `equals`, `safeParse`, `assert`, `hasKey`, `hasKeys`, `narrowKeyTo`.
261
+ assert(isString, input, 'Expected a string');
262
+ input.toUpperCase();
263
+ ```
224
264
 
225
- ### Key Helpers
265
+ ### 8. Narrow object keys
226
266
 
227
- Use `hasKey`/`hasKeys` to check required own properties before refining, and
228
- `narrowKeyTo` when you need to narrow a property to a specific literal value.
267
+ Use key helpers when the important part of a value is one property.
229
268
 
230
269
  ```ts
231
270
  import {
232
271
  hasKey,
233
272
  hasKeys,
234
- isString,
235
273
  isNumber,
274
+ isString,
236
275
  narrowKeyTo,
237
276
  oneOfValues,
238
- or,
239
277
  struct
240
278
  } from 'is-kit';
241
279
 
242
- // Base guard (e.g., via struct)
243
- type User = { id: string; age: number; role: 'admin' | 'guest' | 'trial' };
244
280
  const isUser = struct({
245
- id: isString,
246
- age: isNumber,
247
- role: oneOfValues('admin', 'guest', 'trial')
281
+ id: isNumber,
282
+ name: isString,
283
+ role: oneOfValues('admin', 'member', 'guest')
248
284
  });
249
285
 
250
286
  const hasRole = hasKey('role');
251
287
  const hasRoleAndId = hasKeys('role', 'id');
252
288
  const byRole = narrowKeyTo(isUser, 'role');
253
- const isGuest = byRole('guest'); // Readonly<User> & { role: 'guest' }
254
- const isTrial = byRole('trial'); // Readonly<User> & { role: 'trial' }
255
- const isGuestOrTrial = or(isGuest, isTrial);
289
+ const isAdmin = byRole('admin');
290
+
291
+ const value: unknown = { id: 1, name: 'nyaomaru', role: 'admin' };
256
292
 
257
- declare const value: unknown;
258
293
  if (hasRole(value)) {
259
294
  value.role;
260
295
  }
@@ -264,23 +299,85 @@ if (hasRoleAndId(value)) {
264
299
  value.id;
265
300
  }
266
301
 
267
- if (isGuestOrTrial(value)) {
268
- // value.role is 'guest' | 'trial'
302
+ if (isAdmin(value)) {
303
+ value.role;
304
+ value.name;
269
305
  }
270
306
  ```
271
307
 
272
- ## API Reference
308
+ ## 🌍 Real-world use cases
309
+
310
+ Here are the kinds of problems `is-kit` is especially good at solving:
311
+
312
+ ### API response checks
313
+
314
+ ```ts
315
+ import { isNumber, isString, safeParse, struct } from 'is-kit';
316
+
317
+ const isPost = struct({
318
+ id: isNumber,
319
+ title: isString
320
+ });
321
+
322
+ const parsed = safeParse(isPost, payload);
323
+ if (parsed.valid) {
324
+ renderPost(parsed.value);
325
+ }
326
+ ```
327
+
328
+ ### Safe array filtering
329
+
330
+ ```ts
331
+ import { isNumber } from 'is-kit';
332
+
333
+ const values: unknown[] = [1, 'two', 3];
334
+ const numbers = values.filter(isNumber);
335
+ ```
336
+
337
+ ### Narrowing by discriminant
338
+
339
+ ```ts
340
+ import { isNumber, isString, narrowKeyTo, oneOfValues, struct } from 'is-kit';
341
+
342
+ const isEvent = struct({
343
+ type: oneOfValues('click', 'submit'),
344
+ label: isString,
345
+ timestamp: isNumber
346
+ });
347
+
348
+ const byType = narrowKeyTo(isEvent, 'type');
349
+ const isSubmitEvent = byType('submit');
350
+ ```
351
+
352
+ ## 🎯 API Overview
353
+
354
+ The library is organized around a few small building blocks:
355
+
356
+ - **Primitives**: `isString`, `isNumber`, `isBoolean`, `isInteger`, ...
357
+ - **Composition**: `define`, `and`, `andAll`, `or`, `not`, `oneOf`
358
+ - **Object shapes**: `struct`, `optionalKey`, `hasKey`, `hasKeys`, `narrowKeyTo`
359
+ - **Collections**: `arrayOf`, `tupleOf`, `setOf`, `mapOf`, `recordOf`
360
+ - **Literals**: `oneOfValues`, `equals`, `equalsBy`, `equalsKey`
361
+ - **Nullish handling**: `nullable`, `nonNull`, `nullish`, `optional`, `required`
362
+ - **Result helpers**: `safeParse`, `safeParseWith`, `assert`
363
+
364
+ For the full API list and dedicated pages, use the docs site below.
365
+
366
+ ## 📚 Full Documentation
367
+
368
+ For detailed API pages and more examples, see:
273
369
 
274
- For full API details and runnable examples, visit
370
+ https://is-kit-docs.vercel.app/
275
371
 
276
- [📚 See full document](https://is-kit-docs.vercel.app/)
372
+ ## 👨‍💻 Development
277
373
 
278
- ## Development
374
+ Requires Node 22 and pnpm 10.12.4.
279
375
 
280
- Requires Node 22 and pnpm 10.12.4 (via Corepack or mise).
281
- Want to hack on `is-kit`?
282
- See `DEVELOPER.md` for setup, scripts, and contribution workflow.
376
+ - `pnpm lint`
377
+ - `pnpm build`
378
+ - `pnpm test`
379
+ - `pnpm test:types`
283
380
 
284
- ## Contributing
381
+ See `DEVELOPER.md` for setup details and `CONTRIBUTE.md` for contribution workflow.
285
382
 
286
- See `CONTRIBUTE.md` for workflow, commit style, and tool setup. 🚀
383
+ Pick a guard, compose it, and ship with confidence 🚀
package/dist/index.js CHANGED
@@ -161,8 +161,20 @@ function required(fn) {
161
161
  return (value) => value !== void 0 && fn(value);
162
162
  }
163
163
 
164
+ // src/utils/object-tags.ts
165
+ var objectToString = Object.prototype.toString;
166
+ var OBJECT_TAG_DATE = "[object Date]";
167
+ var OBJECT_TAG_REGEXP = "[object RegExp]";
168
+ var OBJECT_TAG_MAP = "[object Map]";
169
+ var OBJECT_TAG_SET = "[object Set]";
170
+ var OBJECT_TAG_WEAK_MAP = "[object WeakMap]";
171
+ var OBJECT_TAG_WEAK_SET = "[object WeakSet]";
172
+ var OBJECT_TAG_ARRAY_BUFFER = "[object ArrayBuffer]";
173
+ var OBJECT_TAG_DATA_VIEW = "[object DataView]";
174
+ var OBJECT_TAG_ERROR = "[object Error]";
175
+ var getTag = (value) => objectToString.call(value);
176
+
164
177
  // src/core/object.ts
165
- var getTag = (value) => Object.prototype.toString.call(value);
166
178
  var isFunction = define(
167
179
  (value) => typeof value === "function"
168
180
  );
@@ -176,46 +188,46 @@ var isPlainObject = define((value) => {
176
188
  });
177
189
  var isArray = define(Array.isArray);
178
190
  var isDate = define(
179
- (value) => getTag(value) === "[object Date]" && !Number.isNaN(value.getTime())
191
+ (value) => getTag(value) === OBJECT_TAG_DATE && !Number.isNaN(value.getTime())
180
192
  );
181
193
  var isRegExp = define(
182
- (value) => getTag(value) === "[object RegExp]"
194
+ (value) => getTag(value) === OBJECT_TAG_REGEXP
183
195
  );
184
196
  var isMap = define(
185
- (value) => getTag(value) === "[object Map]"
197
+ (value) => getTag(value) === OBJECT_TAG_MAP
186
198
  );
187
199
  var isSet = define(
188
- (value) => getTag(value) === "[object Set]"
200
+ (value) => getTag(value) === OBJECT_TAG_SET
189
201
  );
190
202
  var isWeakMap = define(
191
- (value) => getTag(value) === "[object WeakMap]"
203
+ (value) => getTag(value) === OBJECT_TAG_WEAK_MAP
192
204
  );
193
205
  var isWeakSet = define(
194
- (value) => getTag(value) === "[object WeakSet]"
206
+ (value) => getTag(value) === OBJECT_TAG_WEAK_SET
195
207
  );
196
208
  var isPromiseLike = define((value) => {
197
209
  if (!isObject(value) && !isFunction(value)) return false;
198
- return typeof value.then === "function";
210
+ return isFunction(value.then);
199
211
  });
200
212
  var isIterable = define((value) => {
201
213
  if (!isObject(value) && !isFunction(value)) return false;
202
- return typeof value[Symbol.iterator] === "function";
214
+ return isFunction(value[Symbol.iterator]);
203
215
  });
204
216
  var isAsyncIterable = define((value) => {
205
217
  if (!isObject(value) && !isFunction(value)) return false;
206
- return typeof value[Symbol.asyncIterator] === "function";
218
+ return isFunction(value[Symbol.asyncIterator]);
207
219
  });
208
220
  var isArrayBuffer = define(
209
- (value) => getTag(value) === "[object ArrayBuffer]"
221
+ (value) => getTag(value) === OBJECT_TAG_ARRAY_BUFFER
210
222
  );
211
223
  var isDataView = define(
212
- (value) => getTag(value) === "[object DataView]"
224
+ (value) => getTag(value) === OBJECT_TAG_DATA_VIEW
213
225
  );
214
226
  var isTypedArray = define(
215
- (value) => ArrayBuffer.isView(value) && getTag(value) !== "[object DataView]"
227
+ (value) => ArrayBuffer.isView(value) && getTag(value) !== OBJECT_TAG_DATA_VIEW
216
228
  );
217
229
  var isError = define(
218
- (value) => value instanceof Error || getTag(value) === "[object Error]"
230
+ (value) => value instanceof Error || getTag(value) === OBJECT_TAG_ERROR
219
231
  );
220
232
  var isURL = typeof URL !== "undefined" ? define((value) => value instanceof URL) : define(() => false);
221
233
  var isBlob = typeof Blob !== "undefined" ? define((value) => value instanceof Blob) : define(() => false);
@@ -406,10 +418,6 @@ var ONE_OF_VALUES_LINEAR_SCAN_MAX = 8;
406
418
  var isSingleArrayArg = define(
407
419
  (value) => Array.isArray(value) && value.length === 1 && Array.isArray(value[0])
408
420
  );
409
- var isZeroNumber = and(
410
- isNumber,
411
- predicateToRefine((value) => value === 0)
412
- );
413
421
  var normalizeValues = (args) => isSingleArrayArg(args) ? args[0] : args;
414
422
  var createLinearPredicate = (items) => {
415
423
  return define((input) => {
@@ -421,7 +429,7 @@ var createSetPredicate = (items) => {
421
429
  let hasNegativeZero = false;
422
430
  const valueSet = /* @__PURE__ */ new Set();
423
431
  for (const literalValue of items) {
424
- if (isZeroNumber(literalValue)) {
432
+ if (isZero(literalValue)) {
425
433
  if (Object.is(literalValue, -0)) hasNegativeZero = true;
426
434
  else hasPositiveZero = true;
427
435
  } else {
@@ -429,7 +437,7 @@ var createSetPredicate = (items) => {
429
437
  }
430
438
  }
431
439
  return define((input) => {
432
- if (isZeroNumber(input)) {
440
+ if (isZero(input)) {
433
441
  return Object.is(input, -0) ? hasNegativeZero : hasPositiveZero;
434
442
  }
435
443
  return valueSet.has(input);
package/dist/index.mjs CHANGED
@@ -68,8 +68,20 @@ function required(fn) {
68
68
  return (value) => value !== void 0 && fn(value);
69
69
  }
70
70
 
71
+ // src/utils/object-tags.ts
72
+ var objectToString = Object.prototype.toString;
73
+ var OBJECT_TAG_DATE = "[object Date]";
74
+ var OBJECT_TAG_REGEXP = "[object RegExp]";
75
+ var OBJECT_TAG_MAP = "[object Map]";
76
+ var OBJECT_TAG_SET = "[object Set]";
77
+ var OBJECT_TAG_WEAK_MAP = "[object WeakMap]";
78
+ var OBJECT_TAG_WEAK_SET = "[object WeakSet]";
79
+ var OBJECT_TAG_ARRAY_BUFFER = "[object ArrayBuffer]";
80
+ var OBJECT_TAG_DATA_VIEW = "[object DataView]";
81
+ var OBJECT_TAG_ERROR = "[object Error]";
82
+ var getTag = (value) => objectToString.call(value);
83
+
71
84
  // src/core/object.ts
72
- var getTag = (value) => Object.prototype.toString.call(value);
73
85
  var isFunction = define(
74
86
  (value) => typeof value === "function"
75
87
  );
@@ -83,46 +95,46 @@ var isPlainObject = define((value) => {
83
95
  });
84
96
  var isArray = define(Array.isArray);
85
97
  var isDate = define(
86
- (value) => getTag(value) === "[object Date]" && !Number.isNaN(value.getTime())
98
+ (value) => getTag(value) === OBJECT_TAG_DATE && !Number.isNaN(value.getTime())
87
99
  );
88
100
  var isRegExp = define(
89
- (value) => getTag(value) === "[object RegExp]"
101
+ (value) => getTag(value) === OBJECT_TAG_REGEXP
90
102
  );
91
103
  var isMap = define(
92
- (value) => getTag(value) === "[object Map]"
104
+ (value) => getTag(value) === OBJECT_TAG_MAP
93
105
  );
94
106
  var isSet = define(
95
- (value) => getTag(value) === "[object Set]"
107
+ (value) => getTag(value) === OBJECT_TAG_SET
96
108
  );
97
109
  var isWeakMap = define(
98
- (value) => getTag(value) === "[object WeakMap]"
110
+ (value) => getTag(value) === OBJECT_TAG_WEAK_MAP
99
111
  );
100
112
  var isWeakSet = define(
101
- (value) => getTag(value) === "[object WeakSet]"
113
+ (value) => getTag(value) === OBJECT_TAG_WEAK_SET
102
114
  );
103
115
  var isPromiseLike = define((value) => {
104
116
  if (!isObject(value) && !isFunction(value)) return false;
105
- return typeof value.then === "function";
117
+ return isFunction(value.then);
106
118
  });
107
119
  var isIterable = define((value) => {
108
120
  if (!isObject(value) && !isFunction(value)) return false;
109
- return typeof value[Symbol.iterator] === "function";
121
+ return isFunction(value[Symbol.iterator]);
110
122
  });
111
123
  var isAsyncIterable = define((value) => {
112
124
  if (!isObject(value) && !isFunction(value)) return false;
113
- return typeof value[Symbol.asyncIterator] === "function";
125
+ return isFunction(value[Symbol.asyncIterator]);
114
126
  });
115
127
  var isArrayBuffer = define(
116
- (value) => getTag(value) === "[object ArrayBuffer]"
128
+ (value) => getTag(value) === OBJECT_TAG_ARRAY_BUFFER
117
129
  );
118
130
  var isDataView = define(
119
- (value) => getTag(value) === "[object DataView]"
131
+ (value) => getTag(value) === OBJECT_TAG_DATA_VIEW
120
132
  );
121
133
  var isTypedArray = define(
122
- (value) => ArrayBuffer.isView(value) && getTag(value) !== "[object DataView]"
134
+ (value) => ArrayBuffer.isView(value) && getTag(value) !== OBJECT_TAG_DATA_VIEW
123
135
  );
124
136
  var isError = define(
125
- (value) => value instanceof Error || getTag(value) === "[object Error]"
137
+ (value) => value instanceof Error || getTag(value) === OBJECT_TAG_ERROR
126
138
  );
127
139
  var isURL = typeof URL !== "undefined" ? define((value) => value instanceof URL) : define(() => false);
128
140
  var isBlob = typeof Blob !== "undefined" ? define((value) => value instanceof Blob) : define(() => false);
@@ -313,10 +325,6 @@ var ONE_OF_VALUES_LINEAR_SCAN_MAX = 8;
313
325
  var isSingleArrayArg = define(
314
326
  (value) => Array.isArray(value) && value.length === 1 && Array.isArray(value[0])
315
327
  );
316
- var isZeroNumber = and(
317
- isNumber,
318
- predicateToRefine((value) => value === 0)
319
- );
320
328
  var normalizeValues = (args) => isSingleArrayArg(args) ? args[0] : args;
321
329
  var createLinearPredicate = (items) => {
322
330
  return define((input) => {
@@ -328,7 +336,7 @@ var createSetPredicate = (items) => {
328
336
  let hasNegativeZero = false;
329
337
  const valueSet = /* @__PURE__ */ new Set();
330
338
  for (const literalValue of items) {
331
- if (isZeroNumber(literalValue)) {
339
+ if (isZero(literalValue)) {
332
340
  if (Object.is(literalValue, -0)) hasNegativeZero = true;
333
341
  else hasPositiveZero = true;
334
342
  } else {
@@ -336,7 +344,7 @@ var createSetPredicate = (items) => {
336
344
  }
337
345
  }
338
346
  return define((input) => {
339
- if (isZeroNumber(input)) {
347
+ if (isZero(input)) {
340
348
  return Object.is(input, -0) ? hasNegativeZero : hasPositiveZero;
341
349
  }
342
350
  return valueSet.has(input);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "is-kit",
3
- "version": "1.6.1",
3
+ "version": "1.6.3",
4
4
  "description": "Make 'isXXX' easier. Let's make your code type safe and more readable!",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",