is-kit 1.3.0 → 1.4.1

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
@@ -181,15 +181,24 @@ isAnimal({}); // false
181
181
  - **Define once**: `define<T>(fn)` turns a plain function into a type guard.
182
182
  - **Upgrade predicates**: `predicateToRefine(fn)` adds narrowing.
183
183
  - **Compose freely**: `and`, `or`, `not`, `oneOf`, `arrayOf`, `struct` …
184
- - **Stay ergonomic**: helpers like `nullable`, `optional`, `equals`, `safeParse`, `assert`, `hasKey`, `narrowKeyTo`.
184
+ - **Stay ergonomic**: helpers like `nullable`, `optional`, `equals`, `safeParse`, `assert`, `hasKey`, `hasKeys`, `narrowKeyTo`.
185
185
 
186
186
  ### Key Helpers
187
187
 
188
- Use `hasKey` to check for a required own property before refining, and
188
+ Use `hasKey`/`hasKeys` to check required own properties before refining, and
189
189
  `narrowKeyTo` when you need to narrow a property to a specific literal value.
190
190
 
191
191
  ```ts
192
- import { hasKey, isString, isNumber, narrowKeyTo, or, struct } from 'is-kit';
192
+ import {
193
+ hasKey,
194
+ hasKeys,
195
+ isString,
196
+ isNumber,
197
+ narrowKeyTo,
198
+ oneOfValues,
199
+ or,
200
+ struct
201
+ } from 'is-kit';
193
202
 
194
203
  // Base guard (e.g., via struct)
195
204
  type User = { id: string; age: number; role: 'admin' | 'guest' | 'trial' };
@@ -200,6 +209,7 @@ const isUser = struct({
200
209
  });
201
210
 
202
211
  const hasRole = hasKey('role');
212
+ const hasRoleAndId = hasKeys('role', 'id');
203
213
  const byRole = narrowKeyTo(isUser, 'role');
204
214
  const isGuest = byRole('guest'); // Readonly<User> & { role: 'guest' }
205
215
  const isTrial = byRole('trial'); // Readonly<User> & { role: 'trial' }
@@ -210,6 +220,11 @@ if (hasRole(value)) {
210
220
  value.role;
211
221
  }
212
222
 
223
+ if (hasRoleAndId(value)) {
224
+ value.role;
225
+ value.id;
226
+ }
227
+
213
228
  if (isGuestOrTrial(value)) {
214
229
  // value.role is 'guest' | 'trial'
215
230
  }
package/dist/index.d.mts CHANGED
@@ -476,6 +476,13 @@ declare const isInstanceOf: <C extends abstract new (...args: unknown[]) => unkn
476
476
  * @returns Predicate narrowing to an object with the key present.
477
477
  */
478
478
  declare const hasKey: <K extends PropertyKey>(key: K) => Predicate<Record<K, unknown>>;
479
+ /**
480
+ * Checks whether a value has all specified own keys.
481
+ *
482
+ * @param keys Property keys to check.
483
+ * @returns Predicate narrowing to an object with all keys present.
484
+ */
485
+ declare const hasKeys: <const KS extends readonly [PropertyKey, ...PropertyKey[]]>(...keys: KS) => Predicate<Record<KS[number], unknown>>;
479
486
  /**
480
487
  * Builds a guard that narrows a specific key to the provided literal value.
481
488
  *
@@ -498,4 +505,4 @@ declare function narrowKeyTo<A, K extends keyof A>(guard: Guard<A>, key: K): <co
498
505
  */
499
506
  declare const toBooleanPredicates: <A>(predicates: readonly ((value: A) => boolean)[]) => ReadonlyArray<(value: A) => boolean>;
500
507
 
501
- export { type ChainResult, type Guard, type GuardedOf, type GuardedWithin, type InferSchema, type OutOfGuards, type ParseResult, type Predicate, type Primitive, type Refine, type RefineChain, type Refinement, type Schema, and, andAll, arrayOf, assert, define, equals, equalsBy, equalsKey, guardIn, hasKey, isArray, isArrayBuffer, isAsyncIterable, isBigInt, isBlob, isBoolean, isDataView, isDate, isError, isFiniteNumber, isFunction, isInfiniteNumber, isInstanceOf, isInteger, isIterable, isMap, isNaN, isNegative, isNull, isNumber, isNumberPrimitive, isObject, isPlainObject, isPositive, isPrimitive, isPromiseLike, isRegExp, isSafeInteger, isSet, isString, isSymbol, isTypedArray, isURL, isUndefined, isWeakMap, isWeakSet, isZero, narrowKeyTo, nonNull, not, nullable, nullish, oneOf, oneOfValues, optional, or, predicateToRefine, recordOf, required, safeParse, safeParseWith, struct, toBooleanPredicates, tupleOf };
508
+ export { type ChainResult, type Guard, type GuardedOf, type GuardedWithin, type InferSchema, type OutOfGuards, type ParseResult, type Predicate, type Primitive, type Refine, type RefineChain, type Refinement, type Schema, and, andAll, arrayOf, assert, define, equals, equalsBy, equalsKey, guardIn, hasKey, hasKeys, isArray, isArrayBuffer, isAsyncIterable, isBigInt, isBlob, isBoolean, isDataView, isDate, isError, isFiniteNumber, isFunction, isInfiniteNumber, isInstanceOf, isInteger, isIterable, isMap, isNaN, isNegative, isNull, isNumber, isNumberPrimitive, isObject, isPlainObject, isPositive, isPrimitive, isPromiseLike, isRegExp, isSafeInteger, isSet, isString, isSymbol, isTypedArray, isURL, isUndefined, isWeakMap, isWeakSet, isZero, narrowKeyTo, nonNull, not, nullable, nullish, oneOf, oneOfValues, optional, or, predicateToRefine, recordOf, required, safeParse, safeParseWith, struct, toBooleanPredicates, tupleOf };
package/dist/index.d.ts CHANGED
@@ -476,6 +476,13 @@ declare const isInstanceOf: <C extends abstract new (...args: unknown[]) => unkn
476
476
  * @returns Predicate narrowing to an object with the key present.
477
477
  */
478
478
  declare const hasKey: <K extends PropertyKey>(key: K) => Predicate<Record<K, unknown>>;
479
+ /**
480
+ * Checks whether a value has all specified own keys.
481
+ *
482
+ * @param keys Property keys to check.
483
+ * @returns Predicate narrowing to an object with all keys present.
484
+ */
485
+ declare const hasKeys: <const KS extends readonly [PropertyKey, ...PropertyKey[]]>(...keys: KS) => Predicate<Record<KS[number], unknown>>;
479
486
  /**
480
487
  * Builds a guard that narrows a specific key to the provided literal value.
481
488
  *
@@ -498,4 +505,4 @@ declare function narrowKeyTo<A, K extends keyof A>(guard: Guard<A>, key: K): <co
498
505
  */
499
506
  declare const toBooleanPredicates: <A>(predicates: readonly ((value: A) => boolean)[]) => ReadonlyArray<(value: A) => boolean>;
500
507
 
501
- export { type ChainResult, type Guard, type GuardedOf, type GuardedWithin, type InferSchema, type OutOfGuards, type ParseResult, type Predicate, type Primitive, type Refine, type RefineChain, type Refinement, type Schema, and, andAll, arrayOf, assert, define, equals, equalsBy, equalsKey, guardIn, hasKey, isArray, isArrayBuffer, isAsyncIterable, isBigInt, isBlob, isBoolean, isDataView, isDate, isError, isFiniteNumber, isFunction, isInfiniteNumber, isInstanceOf, isInteger, isIterable, isMap, isNaN, isNegative, isNull, isNumber, isNumberPrimitive, isObject, isPlainObject, isPositive, isPrimitive, isPromiseLike, isRegExp, isSafeInteger, isSet, isString, isSymbol, isTypedArray, isURL, isUndefined, isWeakMap, isWeakSet, isZero, narrowKeyTo, nonNull, not, nullable, nullish, oneOf, oneOfValues, optional, or, predicateToRefine, recordOf, required, safeParse, safeParseWith, struct, toBooleanPredicates, tupleOf };
508
+ export { type ChainResult, type Guard, type GuardedOf, type GuardedWithin, type InferSchema, type OutOfGuards, type ParseResult, type Predicate, type Primitive, type Refine, type RefineChain, type Refinement, type Schema, and, andAll, arrayOf, assert, define, equals, equalsBy, equalsKey, guardIn, hasKey, hasKeys, isArray, isArrayBuffer, isAsyncIterable, isBigInt, isBlob, isBoolean, isDataView, isDate, isError, isFiniteNumber, isFunction, isInfiniteNumber, isInstanceOf, isInteger, isIterable, isMap, isNaN, isNegative, isNull, isNumber, isNumberPrimitive, isObject, isPlainObject, isPositive, isPrimitive, isPromiseLike, isRegExp, isSafeInteger, isSet, isString, isSymbol, isTypedArray, isURL, isUndefined, isWeakMap, isWeakSet, isZero, narrowKeyTo, nonNull, not, nullable, nullish, oneOf, oneOfValues, optional, or, predicateToRefine, recordOf, required, safeParse, safeParseWith, struct, toBooleanPredicates, tupleOf };
package/dist/index.js CHANGED
@@ -30,6 +30,7 @@ __export(index_exports, {
30
30
  equalsKey: () => equalsKey,
31
31
  guardIn: () => guardIn,
32
32
  hasKey: () => hasKey,
33
+ hasKeys: () => hasKeys,
33
34
  isArray: () => isArray,
34
35
  isArrayBuffer: () => isArrayBuffer,
35
36
  isAsyncIterable: () => isAsyncIterable,
@@ -107,7 +108,7 @@ var toBooleanPredicates = (predicates) => predicates;
107
108
 
108
109
  // src/core/logic.ts
109
110
  function and(precondition, condition) {
110
- return function(input) {
111
+ return (input) => {
111
112
  if (precondition(input)) {
112
113
  return condition(input);
113
114
  }
@@ -115,23 +116,19 @@ function and(precondition, condition) {
115
116
  };
116
117
  }
117
118
  function andAll(precondition, ...steps) {
118
- return function(input) {
119
+ return (input) => {
119
120
  if (!precondition(input)) return false;
120
121
  return applyRefinements(input, steps);
121
122
  };
122
123
  }
123
124
  function or(...guards) {
124
125
  const predicates = toBooleanPredicates(guards);
125
- return function(input) {
126
+ return (input) => {
126
127
  return predicates.some((guard) => guard(input));
127
128
  };
128
129
  }
129
130
  function guardIn() {
130
- return function(guard) {
131
- return function(input) {
132
- return guard(input);
133
- };
134
- };
131
+ return (guard) => (input) => guard(input);
135
132
  }
136
133
  function not(fn) {
137
134
  return (input) => !fn(input);
@@ -223,7 +220,7 @@ var isInstanceOf = (constructor) => define((value) => value instanceof construct
223
220
 
224
221
  // src/core/equals.ts
225
222
  function equals(target) {
226
- return function(input) {
223
+ return (input) => {
227
224
  return Object.is(input, target);
228
225
  };
229
226
  }
@@ -238,7 +235,7 @@ function equalsBy(guard, selector) {
238
235
  return (selector2) => createComparator(selector2);
239
236
  }
240
237
  function equalsKey(key, target) {
241
- return function(input) {
238
+ return (input) => {
242
239
  return isObject(input) && Object.prototype.hasOwnProperty.call(input, key) && Object.is(input[key], target);
243
240
  };
244
241
  }
@@ -295,7 +292,7 @@ var isPrimitive = or(
295
292
 
296
293
  // src/core/combinators/array.ts
297
294
  function arrayOf(elementGuard) {
298
- return function(input) {
295
+ return (input) => {
299
296
  if (!Array.isArray(input)) return false;
300
297
  for (const element of input) {
301
298
  if (!elementGuard(element)) return false;
@@ -306,7 +303,7 @@ function arrayOf(elementGuard) {
306
303
 
307
304
  // src/core/combinators/tuple.ts
308
305
  function tupleOf(...guards) {
309
- return function(input) {
306
+ return (input) => {
310
307
  return Array.isArray(input) && input.length === guards.length && guards.every(
311
308
  (guard, index) => guard(input[index])
312
309
  );
@@ -359,7 +356,7 @@ var isZeroNumber = and(
359
356
  );
360
357
  var normalizeValues = (args) => isSingleArrayArg(args) ? args[0] : args;
361
358
  var createLinearPredicate = (items) => {
362
- return function(input) {
359
+ return (input) => {
363
360
  return items.some((value) => Object.is(value, input));
364
361
  };
365
362
  };
@@ -375,7 +372,7 @@ var createSetPredicate = (items) => {
375
372
  valueSet.add(literalValue);
376
373
  }
377
374
  }
378
- return function(input) {
375
+ return (input) => {
379
376
  if (isZeroNumber(input)) {
380
377
  return Object.is(input, -0) ? hasNegativeZero : hasPositiveZero;
381
378
  }
@@ -391,12 +388,20 @@ function oneOfValues(...args) {
391
388
  var hasKey = (key) => define(
392
389
  (input) => isObject(input) && Object.prototype.hasOwnProperty.call(input, key)
393
390
  );
391
+ var hasKeys = (...keys) => {
392
+ if (keys.length === 0) {
393
+ return define(() => false);
394
+ }
395
+ return define(
396
+ (input) => isObject(input) && keys.every((key) => Object.prototype.hasOwnProperty.call(input, key))
397
+ );
398
+ };
394
399
  function narrowKeyTo(guard, key) {
395
- return function(target) {
400
+ return (target) => {
396
401
  const keyEquals = equalsKey(key, target);
397
- return define(function(input) {
398
- return guard(input) && keyEquals(input);
399
- });
402
+ return define(
403
+ (input) => guard(input) && keyEquals(input)
404
+ );
400
405
  };
401
406
  }
402
407
  // Annotate the CommonJS export names for ESM import in node:
@@ -411,6 +416,7 @@ function narrowKeyTo(guard, key) {
411
416
  equalsKey,
412
417
  guardIn,
413
418
  hasKey,
419
+ hasKeys,
414
420
  isArray,
415
421
  isArrayBuffer,
416
422
  isAsyncIterable,
package/dist/index.mjs CHANGED
@@ -18,7 +18,7 @@ var toBooleanPredicates = (predicates) => predicates;
18
18
 
19
19
  // src/core/logic.ts
20
20
  function and(precondition, condition) {
21
- return function(input) {
21
+ return (input) => {
22
22
  if (precondition(input)) {
23
23
  return condition(input);
24
24
  }
@@ -26,23 +26,19 @@ function and(precondition, condition) {
26
26
  };
27
27
  }
28
28
  function andAll(precondition, ...steps) {
29
- return function(input) {
29
+ return (input) => {
30
30
  if (!precondition(input)) return false;
31
31
  return applyRefinements(input, steps);
32
32
  };
33
33
  }
34
34
  function or(...guards) {
35
35
  const predicates = toBooleanPredicates(guards);
36
- return function(input) {
36
+ return (input) => {
37
37
  return predicates.some((guard) => guard(input));
38
38
  };
39
39
  }
40
40
  function guardIn() {
41
- return function(guard) {
42
- return function(input) {
43
- return guard(input);
44
- };
45
- };
41
+ return (guard) => (input) => guard(input);
46
42
  }
47
43
  function not(fn) {
48
44
  return (input) => !fn(input);
@@ -134,7 +130,7 @@ var isInstanceOf = (constructor) => define((value) => value instanceof construct
134
130
 
135
131
  // src/core/equals.ts
136
132
  function equals(target) {
137
- return function(input) {
133
+ return (input) => {
138
134
  return Object.is(input, target);
139
135
  };
140
136
  }
@@ -149,7 +145,7 @@ function equalsBy(guard, selector) {
149
145
  return (selector2) => createComparator(selector2);
150
146
  }
151
147
  function equalsKey(key, target) {
152
- return function(input) {
148
+ return (input) => {
153
149
  return isObject(input) && Object.prototype.hasOwnProperty.call(input, key) && Object.is(input[key], target);
154
150
  };
155
151
  }
@@ -206,7 +202,7 @@ var isPrimitive = or(
206
202
 
207
203
  // src/core/combinators/array.ts
208
204
  function arrayOf(elementGuard) {
209
- return function(input) {
205
+ return (input) => {
210
206
  if (!Array.isArray(input)) return false;
211
207
  for (const element of input) {
212
208
  if (!elementGuard(element)) return false;
@@ -217,7 +213,7 @@ function arrayOf(elementGuard) {
217
213
 
218
214
  // src/core/combinators/tuple.ts
219
215
  function tupleOf(...guards) {
220
- return function(input) {
216
+ return (input) => {
221
217
  return Array.isArray(input) && input.length === guards.length && guards.every(
222
218
  (guard, index) => guard(input[index])
223
219
  );
@@ -270,7 +266,7 @@ var isZeroNumber = and(
270
266
  );
271
267
  var normalizeValues = (args) => isSingleArrayArg(args) ? args[0] : args;
272
268
  var createLinearPredicate = (items) => {
273
- return function(input) {
269
+ return (input) => {
274
270
  return items.some((value) => Object.is(value, input));
275
271
  };
276
272
  };
@@ -286,7 +282,7 @@ var createSetPredicate = (items) => {
286
282
  valueSet.add(literalValue);
287
283
  }
288
284
  }
289
- return function(input) {
285
+ return (input) => {
290
286
  if (isZeroNumber(input)) {
291
287
  return Object.is(input, -0) ? hasNegativeZero : hasPositiveZero;
292
288
  }
@@ -302,12 +298,20 @@ function oneOfValues(...args) {
302
298
  var hasKey = (key) => define(
303
299
  (input) => isObject(input) && Object.prototype.hasOwnProperty.call(input, key)
304
300
  );
301
+ var hasKeys = (...keys) => {
302
+ if (keys.length === 0) {
303
+ return define(() => false);
304
+ }
305
+ return define(
306
+ (input) => isObject(input) && keys.every((key) => Object.prototype.hasOwnProperty.call(input, key))
307
+ );
308
+ };
305
309
  function narrowKeyTo(guard, key) {
306
- return function(target) {
310
+ return (target) => {
307
311
  const keyEquals = equalsKey(key, target);
308
- return define(function(input) {
309
- return guard(input) && keyEquals(input);
310
- });
312
+ return define(
313
+ (input) => guard(input) && keyEquals(input)
314
+ );
311
315
  };
312
316
  }
313
317
  export {
@@ -321,6 +325,7 @@ export {
321
325
  equalsKey,
322
326
  guardIn,
323
327
  hasKey,
328
+ hasKeys,
324
329
  isArray,
325
330
  isArrayBuffer,
326
331
  isAsyncIterable,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "is-kit",
3
- "version": "1.3.0",
3
+ "version": "1.4.1",
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",