is-kit 1.9.0 → 1.10.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/README.md CHANGED
@@ -116,6 +116,7 @@ This is the core idea of `is-kit`:
116
116
  If you are new to the library, these are the pieces to remember:
117
117
 
118
118
  - `define<T>(fn)` turns a boolean check into a typed guard.
119
+ - `lazy(factory)` defers a guard definition so recursive structures can refer to themselves.
119
120
  - `predicateToRefine(fn)` upgrades an existing predicate so it can participate in narrowing chains.
120
121
  - `struct({...})` builds an object-shape guard.
121
122
  - `safeParse(guard, value)` gives you a small tagged result object.
@@ -224,7 +225,31 @@ import { oneOfValues } from 'is-kit';
224
225
  const isStatus = oneOfValues('draft', 'published', 'archived');
225
226
  ```
226
227
 
227
- ### 6. Handle null and undefined explicitly
228
+ ### 6. Validate recursive structures
229
+
230
+ Use `lazy` when a guard needs to refer to itself. The factory runs on first use,
231
+ and the resulting guard is cached.
232
+
233
+ ```ts
234
+ import { arrayOf, isString, lazy, typedStruct } from 'is-kit';
235
+ import type { Predicate } from 'is-kit';
236
+
237
+ type Tree = {
238
+ readonly value: string;
239
+ readonly children: readonly Tree[];
240
+ };
241
+
242
+ const isTree: Predicate<Tree> = lazy(() =>
243
+ typedStruct<Tree>()({
244
+ value: isString,
245
+ children: arrayOf(isTree)
246
+ })
247
+ );
248
+ ```
249
+
250
+ `lazy` does not detect circular references in the input value.
251
+
252
+ ### 7. Handle null and undefined explicitly
228
253
 
229
254
  Use the nullish helpers to say exactly what is allowed.
230
255
 
@@ -245,7 +270,7 @@ const isDefinedString = required(optional(isString));
245
270
  const isNonNullString = nonNull(nullable(isString));
246
271
  ```
247
272
 
248
- ### 7. Parse or assert unknown input
273
+ ### 8. Parse or assert unknown input
249
274
 
250
275
  Use `safeParse` when you want a result object, and `assert` when invalid data should stop execution.
251
276
 
@@ -264,7 +289,7 @@ assert(isString, input, 'Expected a string');
264
289
  input.toUpperCase();
265
290
  ```
266
291
 
267
- ### 8. Decode and validate JSON input
292
+ ### 9. Decode and validate JSON input
268
293
 
269
294
  Use `safeJsonParse` at a JSON text boundary. It decodes the text, treats the
270
295
  result as `unknown`, and only returns the value after the guard accepts it.
@@ -296,7 +321,7 @@ if (result.valid) {
296
321
  coercion and does not depend on a transport or schema format such as HTTP or
297
322
  OpenAPI.
298
323
 
299
- ### 9. Narrow object keys
324
+ ### 10. Narrow object keys
300
325
 
301
326
  Use key helpers when the important part of a value is one property.
302
327
 
package/dist/index.d.mts CHANGED
@@ -133,6 +133,17 @@ declare const hasKeys: <const KS extends readonly [PropertyKey, ...PropertyKey[]
133
133
  */
134
134
  declare function narrowKeyTo<A, K extends keyof A>(guard: Guard<A>, key: K): <const T extends A[K]>(target: T) => Predicate<A & Record<K, T>>;
135
135
 
136
+ /**
137
+ * Creates a predicate whose implementation is initialized on first use.
138
+ *
139
+ * The initialized predicate is cached after the factory returns successfully.
140
+ * Circular references in the input value are not detected.
141
+ *
142
+ * @param factory Function that creates the predicate when it is first evaluated.
143
+ * @returns Predicate that delegates to the lazily initialized implementation.
144
+ */
145
+ declare function lazy<T>(factory: () => Predicate<T>): Predicate<T>;
146
+
136
147
  /**
137
148
  * Combines a precondition guard with an additional refinement to narrow the type.
138
149
  *
@@ -653,4 +664,4 @@ declare const everyOwnEnumerableEntry: (values: Record<string, unknown>, keyPred
653
664
  */
654
665
  declare const toBooleanPredicates: <A>(predicates: readonly ((value: A) => boolean)[]) => ReadonlyArray<(value: A) => boolean>;
655
666
 
656
- export { type ChainResult, type Guard, type GuardedOf, type GuardedWithin, type InferSchema, type OptionalSchemaField, type OutOfGuards, type ParseResult, type Predicate, type Primitive, type Refine, type RefineChain, type Refinement, type Schema, type SchemaField, and, andAll, arrayOf, assert, define, equals, equalsBy, equalsKey, everyArrayValue, everyMapEntry, everyOwnEnumerableEntry, everySetValue, everyTupleValue, 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, mapOf, narrowKeyTo, nonEmptyArrayOf, nonNull, not, nullable, nullish, oneOf, oneOfValues, optional, optionalKey, or, predicateToRefine, recordOf, required, safeJsonParse, safeParse, safeParseWith, setOf, struct, toBooleanPredicates, tupleOf, typedStruct };
667
+ export { type ChainResult, type Guard, type GuardedOf, type GuardedWithin, type InferSchema, type OptionalSchemaField, type OutOfGuards, type ParseResult, type Predicate, type Primitive, type Refine, type RefineChain, type Refinement, type Schema, type SchemaField, and, andAll, arrayOf, assert, define, equals, equalsBy, equalsKey, everyArrayValue, everyMapEntry, everyOwnEnumerableEntry, everySetValue, everyTupleValue, 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, lazy, mapOf, narrowKeyTo, nonEmptyArrayOf, nonNull, not, nullable, nullish, oneOf, oneOfValues, optional, optionalKey, or, predicateToRefine, recordOf, required, safeJsonParse, safeParse, safeParseWith, setOf, struct, toBooleanPredicates, tupleOf, typedStruct };
package/dist/index.d.ts CHANGED
@@ -133,6 +133,17 @@ declare const hasKeys: <const KS extends readonly [PropertyKey, ...PropertyKey[]
133
133
  */
134
134
  declare function narrowKeyTo<A, K extends keyof A>(guard: Guard<A>, key: K): <const T extends A[K]>(target: T) => Predicate<A & Record<K, T>>;
135
135
 
136
+ /**
137
+ * Creates a predicate whose implementation is initialized on first use.
138
+ *
139
+ * The initialized predicate is cached after the factory returns successfully.
140
+ * Circular references in the input value are not detected.
141
+ *
142
+ * @param factory Function that creates the predicate when it is first evaluated.
143
+ * @returns Predicate that delegates to the lazily initialized implementation.
144
+ */
145
+ declare function lazy<T>(factory: () => Predicate<T>): Predicate<T>;
146
+
136
147
  /**
137
148
  * Combines a precondition guard with an additional refinement to narrow the type.
138
149
  *
@@ -653,4 +664,4 @@ declare const everyOwnEnumerableEntry: (values: Record<string, unknown>, keyPred
653
664
  */
654
665
  declare const toBooleanPredicates: <A>(predicates: readonly ((value: A) => boolean)[]) => ReadonlyArray<(value: A) => boolean>;
655
666
 
656
- export { type ChainResult, type Guard, type GuardedOf, type GuardedWithin, type InferSchema, type OptionalSchemaField, type OutOfGuards, type ParseResult, type Predicate, type Primitive, type Refine, type RefineChain, type Refinement, type Schema, type SchemaField, and, andAll, arrayOf, assert, define, equals, equalsBy, equalsKey, everyArrayValue, everyMapEntry, everyOwnEnumerableEntry, everySetValue, everyTupleValue, 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, mapOf, narrowKeyTo, nonEmptyArrayOf, nonNull, not, nullable, nullish, oneOf, oneOfValues, optional, optionalKey, or, predicateToRefine, recordOf, required, safeJsonParse, safeParse, safeParseWith, setOf, struct, toBooleanPredicates, tupleOf, typedStruct };
667
+ export { type ChainResult, type Guard, type GuardedOf, type GuardedWithin, type InferSchema, type OptionalSchemaField, type OutOfGuards, type ParseResult, type Predicate, type Primitive, type Refine, type RefineChain, type Refinement, type Schema, type SchemaField, and, andAll, arrayOf, assert, define, equals, equalsBy, equalsKey, everyArrayValue, everyMapEntry, everyOwnEnumerableEntry, everySetValue, everyTupleValue, 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, lazy, mapOf, narrowKeyTo, nonEmptyArrayOf, nonNull, not, nullable, nullish, oneOf, oneOfValues, optional, optionalKey, or, predicateToRefine, recordOf, required, safeJsonParse, safeParse, safeParseWith, setOf, struct, toBooleanPredicates, tupleOf, typedStruct };
package/dist/index.js CHANGED
@@ -73,6 +73,7 @@ __export(index_exports, {
73
73
  isWeakMap: () => isWeakMap,
74
74
  isWeakSet: () => isWeakSet,
75
75
  isZero: () => isZero,
76
+ lazy: () => lazy,
76
77
  mapOf: () => mapOf,
77
78
  narrowKeyTo: () => narrowKeyTo,
78
79
  nonEmptyArrayOf: () => nonEmptyArrayOf,
@@ -220,6 +221,15 @@ function narrowKeyTo(guard, key) {
220
221
  };
221
222
  }
222
223
 
224
+ // src/core/lazy.ts
225
+ function lazy(factory) {
226
+ let predicate;
227
+ return (value) => {
228
+ predicate ??= factory();
229
+ return predicate(value);
230
+ };
231
+ }
232
+
223
233
  // src/utils/guard-collections.ts
224
234
  var everyArrayValue = (values, predicate) => {
225
235
  for (const value of values) {
@@ -560,6 +570,7 @@ function tupleOf(...guards) {
560
570
  isWeakMap,
561
571
  isWeakSet,
562
572
  isZero,
573
+ lazy,
563
574
  mapOf,
564
575
  narrowKeyTo,
565
576
  nonEmptyArrayOf,
package/dist/index.mjs CHANGED
@@ -119,6 +119,15 @@ function narrowKeyTo(guard, key) {
119
119
  };
120
120
  }
121
121
 
122
+ // src/core/lazy.ts
123
+ function lazy(factory) {
124
+ let predicate;
125
+ return (value) => {
126
+ predicate ??= factory();
127
+ return predicate(value);
128
+ };
129
+ }
130
+
122
131
  // src/utils/guard-collections.ts
123
132
  var everyArrayValue = (values, predicate) => {
124
133
  for (const value of values) {
@@ -458,6 +467,7 @@ export {
458
467
  isWeakMap,
459
468
  isWeakSet,
460
469
  isZero,
470
+ lazy,
461
471
  mapOf,
462
472
  narrowKeyTo,
463
473
  nonEmptyArrayOf,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "is-kit",
3
- "version": "1.9.0",
3
+ "version": "1.10.0",
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",