is-kit 1.10.0 → 1.11.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 +75 -1
- package/dist/index.d.mts +90 -6
- package/dist/index.d.ts +90 -6
- package/dist/index.js +55 -42
- package/dist/index.mjs +53 -42
- package/docs/README.md +101 -0
- package/docs/agent-rules.md +63 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -111,6 +111,69 @@ This is the core idea of `is-kit`:
|
|
|
111
111
|
2. Compose them.
|
|
112
112
|
3. Reuse them anywhere TypeScript narrowing matters.
|
|
113
113
|
|
|
114
|
+
## 🧭 Guard Composition Guide
|
|
115
|
+
|
|
116
|
+
When writing reusable guards with `is-kit`, start from the library primitives:
|
|
117
|
+
use `define` for custom runtime checks, and use logic combinators such as
|
|
118
|
+
`and`, `or`, and `not` when combining existing guards. This keeps the result
|
|
119
|
+
reusable as a named guard and preserves the type-level intent in hover,
|
|
120
|
+
completion, and generated declarations.
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
import {
|
|
124
|
+
and,
|
|
125
|
+
define,
|
|
126
|
+
isNil,
|
|
127
|
+
isNumber,
|
|
128
|
+
isString,
|
|
129
|
+
nullish,
|
|
130
|
+
or,
|
|
131
|
+
predicateToRefine
|
|
132
|
+
} from 'is-kit';
|
|
133
|
+
|
|
134
|
+
const isId = or(isString, isNumber);
|
|
135
|
+
const isNullishString = nullish(isString);
|
|
136
|
+
|
|
137
|
+
const isSlug = define<string>(
|
|
138
|
+
(value) => isString(value) && /^[a-z0-9-]+$/.test(value)
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
const isPositiveNumber = and(
|
|
142
|
+
isNumber,
|
|
143
|
+
predicateToRefine<number>((value) => value > 0)
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
isNil(null); // true
|
|
147
|
+
isNil(undefined); // true
|
|
148
|
+
isId('user-1'); // true
|
|
149
|
+
isNullishString(undefined); // true
|
|
150
|
+
isSlug('release-110'); // true
|
|
151
|
+
isPositiveNumber(1); // true
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Prefer these forms when generating or reviewing code:
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
declare const value: unknown;
|
|
158
|
+
|
|
159
|
+
// Prefer
|
|
160
|
+
const isId = or(isString, isNumber);
|
|
161
|
+
const isMaybeName = nullish(isString);
|
|
162
|
+
const isSlug = define<string>(
|
|
163
|
+
(value) => isString(value) && /^[a-z0-9-]+$/.test(value)
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
// Avoid
|
|
167
|
+
const isId = (value: unknown) => isString(value) || isNumber(value);
|
|
168
|
+
const isMaybeName = (value: unknown) => value == null || isString(value);
|
|
169
|
+
const isSlug = (value: unknown): value is string =>
|
|
170
|
+
isString(value) && /^[a-z0-9-]+$/.test(value);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
For AI agents or repository-wide conventions, copy
|
|
174
|
+
[docs/agent-rules.md](./docs/agent-rules.md) into the consumer repository's
|
|
175
|
+
agent instructions.
|
|
176
|
+
|
|
114
177
|
## ⌚ A 30-second Mental Model
|
|
115
178
|
|
|
116
179
|
If you are new to the library, these are the pieces to remember:
|
|
@@ -270,6 +333,17 @@ const isDefinedString = required(optional(isString));
|
|
|
270
333
|
const isNonNullString = nonNull(nullable(isString));
|
|
271
334
|
```
|
|
272
335
|
|
|
336
|
+
For a plain "is it `null` or `undefined`?" check, reach for `isNil` instead of
|
|
337
|
+
hand-rolling `isNull(x) || isUndefined(x)`:
|
|
338
|
+
|
|
339
|
+
```ts
|
|
340
|
+
import { isNil } from 'is-kit';
|
|
341
|
+
|
|
342
|
+
isNil(null); // true
|
|
343
|
+
isNil(undefined); // true
|
|
344
|
+
isNil(0); // false
|
|
345
|
+
```
|
|
346
|
+
|
|
273
347
|
### 8. Parse or assert unknown input
|
|
274
348
|
|
|
275
349
|
Use `safeParse` when you want a result object, and `assert` when invalid data should stop execution.
|
|
@@ -434,7 +508,7 @@ The library is organized around a few small building blocks:
|
|
|
434
508
|
- **Object shapes**: `struct`, `optionalKey`, `hasKey`, `hasKeys`, `narrowKeyTo`
|
|
435
509
|
- **Collections**: `arrayOf`, `nonEmptyArrayOf`, `tupleOf`, `setOf`, `mapOf`, `recordOf`
|
|
436
510
|
- **Literals**: `oneOfValues`, `equals`, `equalsBy`, `equalsKey`
|
|
437
|
-
- **Nullish handling**: `nullable`, `nonNull`, `nullish`, `optional`, `required`
|
|
511
|
+
- **Nullish handling**: `isNil`, `nullable`, `nonNull`, `nullish`, `optional`, `required`
|
|
438
512
|
- **Result helpers**: `safeParse`, `safeParseWith`, `safeJsonParse`, `assert`
|
|
439
513
|
|
|
440
514
|
For the full API list and dedicated pages, use the docs site below.
|
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* is-kit guard authoring guide:
|
|
3
|
+
* - Use define<T>(...) for reusable custom runtime checks.
|
|
4
|
+
* - Use and, andAll, or, and not to compose existing guards instead of
|
|
5
|
+
* hand-written boolean wrappers.
|
|
6
|
+
* - Use nullable, optional, or nullish to widen guards for nullish values.
|
|
7
|
+
* - Use struct or typedStruct for object-shape guards.
|
|
8
|
+
*/
|
|
1
9
|
type Predicate<T> = (value: unknown) => value is T;
|
|
2
10
|
type Refinement<A, B extends A> = (value: A) => value is B;
|
|
3
11
|
type Guard<T> = Predicate<T>;
|
|
@@ -69,12 +77,18 @@ declare function assert<A, B extends A>(refine: Refine<A, B>, value: A, message?
|
|
|
69
77
|
|
|
70
78
|
/**
|
|
71
79
|
* Wraps a user function as a typed predicate.
|
|
80
|
+
* Prefer `define<T>(...)` when creating a reusable custom guard from a runtime
|
|
81
|
+
* boolean check.
|
|
72
82
|
*
|
|
73
83
|
* Note: The correctness of the predicate is the caller's responsibility.
|
|
74
84
|
* Its result is coerced to a boolean using `!!` for consistent guard behavior.
|
|
75
85
|
*
|
|
76
86
|
* @param fn Function that returns truthy when the value matches the target shape.
|
|
77
87
|
* @returns Predicate narrowing to the intended type when it returns true.
|
|
88
|
+
* @example
|
|
89
|
+
* const isSlug = define<string>(
|
|
90
|
+
* (value) => isString(value) && /^[a-z0-9-]+$/.test(value)
|
|
91
|
+
* );
|
|
78
92
|
*/
|
|
79
93
|
declare function define<T>(fn: (value: unknown) => value is T): Predicate<T>;
|
|
80
94
|
declare function define<T>(fn: (value: unknown) => boolean): Predicate<T>;
|
|
@@ -146,49 +160,76 @@ declare function lazy<T>(factory: () => Predicate<T>): Predicate<T>;
|
|
|
146
160
|
|
|
147
161
|
/**
|
|
148
162
|
* Combines a precondition guard with an additional refinement to narrow the type.
|
|
163
|
+
* Prefer this over hand-written `precondition(x) && condition(x)` when the
|
|
164
|
+
* composed predicate should be reused as a guard.
|
|
149
165
|
*
|
|
150
166
|
* @param precondition Broad guard evaluated first; short-circuits on failure.
|
|
151
167
|
* @param condition Refinement evaluated only when `precondition` passes.
|
|
152
168
|
* @returns Predicate that narrows the input to a subtype.
|
|
169
|
+
* @example
|
|
170
|
+
* const isPositiveNumber = and(
|
|
171
|
+
* isNumber,
|
|
172
|
+
* predicateToRefine<number>((value) => value > 0)
|
|
173
|
+
* );
|
|
174
|
+
* @see andAll
|
|
153
175
|
*/
|
|
154
176
|
declare function and<A, B extends A>(precondition: Guard<A>, condition: Refine<A, B>): Predicate<B>;
|
|
155
177
|
/**
|
|
156
178
|
* Chains a sequence of refinements after a precondition, returning the final guard type.
|
|
179
|
+
* Use this instead of nested `&&` checks when each step should keep narrowing
|
|
180
|
+
* the next refinement.
|
|
157
181
|
*
|
|
158
182
|
* @param precondition Initial guard applied first.
|
|
159
183
|
* @param steps Subsequent refinements applied in order.
|
|
160
184
|
* @returns Guard reflecting the result of the refinement chain.
|
|
185
|
+
* @example
|
|
186
|
+
* const isPublicTitle = andAll(isString, minLength(4), startsWithPublic);
|
|
187
|
+
* @see and
|
|
161
188
|
*/
|
|
162
189
|
declare function andAll<A>(precondition: Guard<A>): Guard<A>;
|
|
163
190
|
declare function andAll<A, B extends A>(precondition: Guard<A>, step1: Refine<A, B>): Guard<B>;
|
|
164
191
|
declare function andAll<A, B extends A, C extends B>(precondition: Guard<A>, step1: Refine<A, B>, step2: Refine<B, C>): Guard<C>;
|
|
165
192
|
/**
|
|
166
193
|
* Logical OR over multiple guards.
|
|
194
|
+
* Prefer this over hand-written `guardA(x) || guardB(x)` when the composed
|
|
195
|
+
* predicate should be reused as a guard.
|
|
167
196
|
*
|
|
168
197
|
* @param guards Guards to evaluate; passes if any guard passes.
|
|
169
198
|
* @returns Guard for the union of all guarded types.
|
|
199
|
+
* @example
|
|
200
|
+
* const isId = or(isString, isNumber);
|
|
201
|
+
* @see oneOf
|
|
170
202
|
*/
|
|
171
203
|
declare function or<P extends readonly Guard<unknown>[]>(...guards: P): Guard<OutOfGuards<P>>;
|
|
172
204
|
/**
|
|
173
205
|
* Adapts a guard so it can be used as a refinement within a known supertype.
|
|
174
206
|
*
|
|
175
207
|
* @returns Function that converts a `Guard<T>` into a `Refine<A, T>` when `T extends A`.
|
|
208
|
+
* @see and
|
|
176
209
|
*/
|
|
177
210
|
declare function guardIn<A>(): <T extends A>(guard: Guard<T>) => Refine<A, T>;
|
|
178
211
|
/**
|
|
179
212
|
* Logical negation of a guard/refinement.
|
|
213
|
+
* Use this when a negated predicate should be named and reused.
|
|
180
214
|
*
|
|
181
215
|
* @param guard Guard or refinement to negate.
|
|
182
216
|
* @returns Refinement excluding the guarded subtype from the input type.
|
|
217
|
+
* @example
|
|
218
|
+
* const isPresent = not(isNil);
|
|
183
219
|
*/
|
|
184
220
|
declare function not<A, T>(guard: Guard<T>): Refine<A, Exclude<A, Extract<A, T>>>;
|
|
185
221
|
declare function not<A, B extends A>(refine: Refine<A, B>): Refine<A, Exclude<A, B>>;
|
|
186
222
|
|
|
187
223
|
/**
|
|
188
224
|
* Allows `null` in addition to values accepted by the given guard/refinement.
|
|
225
|
+
* Use this instead of hand-writing `value === null || guard(value)` when the
|
|
226
|
+
* widened predicate should stay reusable.
|
|
189
227
|
*
|
|
190
228
|
* @param guard Guard/refinement for the base type.
|
|
191
229
|
* @returns Guard/refinement widened to include `null`.
|
|
230
|
+
* @example
|
|
231
|
+
* const isNullableString = nullable(isString);
|
|
232
|
+
* @see nullish
|
|
192
233
|
*/
|
|
193
234
|
declare function nullable<T>(guard: Guard<T>): Guard<T | null>;
|
|
194
235
|
declare function nullable<A, B extends A>(refine: Refine<A, B>): Refine<A | null, B | null>;
|
|
@@ -197,22 +238,33 @@ declare function nullable<A, B extends A>(refine: Refine<A, B>): Refine<A | null
|
|
|
197
238
|
*
|
|
198
239
|
* @param guard Guard/refinement possibly including `null`.
|
|
199
240
|
* @returns Guard/refinement with `null` excluded.
|
|
241
|
+
* @example
|
|
242
|
+
* const isNonNullString = nonNull(nullable(isString));
|
|
200
243
|
*/
|
|
201
244
|
declare function nonNull<T>(guard: Guard<T>): Guard<Exclude<T, null>>;
|
|
202
245
|
declare function nonNull<A, B extends A>(refine: Refine<A, B>): Refine<Exclude<A, null>, Exclude<B, null>>;
|
|
203
246
|
/**
|
|
204
247
|
* Allows `null` or `undefined` in addition to values accepted by the guard.
|
|
248
|
+
* Use this instead of hand-writing `isNil(value) || guard(value)` when widening
|
|
249
|
+
* another guard.
|
|
205
250
|
*
|
|
206
251
|
* @param guard Guard/refinement for the base type.
|
|
207
252
|
* @returns Guard/refinement widened to include `null | undefined`.
|
|
253
|
+
* @example
|
|
254
|
+
* const isNullishString = nullish(isString);
|
|
255
|
+
* @see isNil
|
|
208
256
|
*/
|
|
209
257
|
declare function nullish<T>(guard: Guard<T>): Guard<T | null | undefined>;
|
|
210
258
|
declare function nullish<A, B extends A>(refine: Refine<A, B>): Refine<A | null | undefined, B | null | undefined>;
|
|
211
259
|
/**
|
|
212
260
|
* Allows `undefined` in addition to values accepted by the guard.
|
|
261
|
+
* Use this for value-level optionality. For optional object keys in `struct`,
|
|
262
|
+
* use `optionalKey(...)`.
|
|
213
263
|
*
|
|
214
264
|
* @param guard Guard/refinement for the base type.
|
|
215
265
|
* @returns Guard/refinement widened to include `undefined`.
|
|
266
|
+
* @example
|
|
267
|
+
* const isOptionalString = optional(isString);
|
|
216
268
|
*/
|
|
217
269
|
declare function optional<T>(guard: Guard<T>): Guard<T | undefined>;
|
|
218
270
|
declare function optional<A, B extends A>(refine: Refine<A, B>): Refine<A | undefined, B | undefined>;
|
|
@@ -221,6 +273,8 @@ declare function optional<A, B extends A>(refine: Refine<A, B>): Refine<A | unde
|
|
|
221
273
|
*
|
|
222
274
|
* @param guard Guard/refinement that may accept `undefined`.
|
|
223
275
|
* @returns Guard/refinement with `undefined` removed.
|
|
276
|
+
* @example
|
|
277
|
+
* const isRequiredString = required(optional(isString));
|
|
224
278
|
*/
|
|
225
279
|
declare function required<T>(guard: Guard<T | undefined>): Guard<T>;
|
|
226
280
|
declare function required<A, B extends A>(refine: Refine<A | undefined, B | undefined>): Refine<A, B>;
|
|
@@ -351,15 +405,38 @@ declare const isSymbol: Predicate<symbol>;
|
|
|
351
405
|
/**
|
|
352
406
|
* Checks whether a value is exactly `undefined`.
|
|
353
407
|
*
|
|
408
|
+
* For reusable nullish checks, use {@link isNil} or compose a named guard with
|
|
409
|
+
* {@link or} once and reuse it.
|
|
410
|
+
*
|
|
354
411
|
* @returns Predicate narrowing to `undefined`.
|
|
412
|
+
* @see isNil
|
|
355
413
|
*/
|
|
356
414
|
declare const isUndefined: Predicate<undefined>;
|
|
357
415
|
/**
|
|
358
416
|
* Checks whether a value is exactly `null`.
|
|
359
417
|
*
|
|
418
|
+
* For reusable nullish checks, use {@link isNil} or compose a named guard with
|
|
419
|
+
* {@link or} once and reuse it.
|
|
420
|
+
*
|
|
360
421
|
* @returns Predicate narrowing to `null`.
|
|
422
|
+
* @see isNil
|
|
361
423
|
*/
|
|
362
424
|
declare const isNull: Predicate<null>;
|
|
425
|
+
/**
|
|
426
|
+
* Checks whether a value is `null` or `undefined` (nullish).
|
|
427
|
+
*
|
|
428
|
+
* Prefer this over hand-rolling `isNull(x) || isUndefined(x)`: it is the same
|
|
429
|
+
* check expressed once. To widen an existing guard so it also accepts nullish
|
|
430
|
+
* values, use {@link nullish} instead.
|
|
431
|
+
*
|
|
432
|
+
* @returns Predicate narrowing to `null | undefined`.
|
|
433
|
+
* @example
|
|
434
|
+
* isNil(null); // true
|
|
435
|
+
* isNil(undefined); // true
|
|
436
|
+
* isNil(0); // false
|
|
437
|
+
* @see or
|
|
438
|
+
*/
|
|
439
|
+
declare const isNil: Guard<null | undefined>;
|
|
363
440
|
/**
|
|
364
441
|
* Checks whether a value is a JavaScript primitive.
|
|
365
442
|
*
|
|
@@ -485,6 +562,12 @@ declare const isURL: Guard<URL>;
|
|
|
485
562
|
* @returns Predicate narrowing to `Blob` when supported; otherwise always false.
|
|
486
563
|
*/
|
|
487
564
|
declare const isBlob: Guard<Blob>;
|
|
565
|
+
/**
|
|
566
|
+
* Checks whether a value is a `File` (in environments with File available).
|
|
567
|
+
*
|
|
568
|
+
* @returns Predicate narrowing to `File` when supported; otherwise always false.
|
|
569
|
+
*/
|
|
570
|
+
declare const isFile: Guard<File>;
|
|
488
571
|
/**
|
|
489
572
|
* Creates a guard that checks whether a value is an instance of `constructor`.
|
|
490
573
|
*
|
|
@@ -613,6 +696,7 @@ declare function tupleOf<const Fs extends readonly Predicate<unknown>[]>(...guar
|
|
|
613
696
|
readonly [K in keyof Fs]: GuardedOf<Fs[K]>;
|
|
614
697
|
}>;
|
|
615
698
|
|
|
699
|
+
type BooleanPredicate<T> = (value: T) => boolean;
|
|
616
700
|
/**
|
|
617
701
|
* Checks whether every array element satisfies the provided predicate.
|
|
618
702
|
*
|
|
@@ -620,7 +704,7 @@ declare function tupleOf<const Fs extends readonly Predicate<unknown>[]>(...guar
|
|
|
620
704
|
* @param predicate Predicate applied to each element.
|
|
621
705
|
* @returns Whether all elements satisfy `predicate`.
|
|
622
706
|
*/
|
|
623
|
-
declare const everyArrayValue: (values: readonly unknown[], predicate:
|
|
707
|
+
declare const everyArrayValue: (values: readonly unknown[], predicate: BooleanPredicate<unknown>) => boolean;
|
|
624
708
|
/**
|
|
625
709
|
* Checks whether a tuple matches the provided element predicates in order.
|
|
626
710
|
*
|
|
@@ -628,7 +712,7 @@ declare const everyArrayValue: (values: readonly unknown[], predicate: (value: u
|
|
|
628
712
|
* @param predicates Predicates aligned to each tuple index.
|
|
629
713
|
* @returns Whether lengths match and each index passes.
|
|
630
714
|
*/
|
|
631
|
-
declare const everyTupleValue: (values: readonly unknown[], predicates: readonly
|
|
715
|
+
declare const everyTupleValue: (values: readonly unknown[], predicates: readonly BooleanPredicate<unknown>[]) => boolean;
|
|
632
716
|
/**
|
|
633
717
|
* Checks whether every set value satisfies the provided predicate.
|
|
634
718
|
*
|
|
@@ -636,7 +720,7 @@ declare const everyTupleValue: (values: readonly unknown[], predicates: readonly
|
|
|
636
720
|
* @param predicate Predicate applied to each value.
|
|
637
721
|
* @returns Whether all set values satisfy `predicate`.
|
|
638
722
|
*/
|
|
639
|
-
declare const everySetValue: (values: ReadonlySet<unknown>, predicate:
|
|
723
|
+
declare const everySetValue: (values: ReadonlySet<unknown>, predicate: BooleanPredicate<unknown>) => boolean;
|
|
640
724
|
/**
|
|
641
725
|
* Checks whether every map entry satisfies the provided key and value predicates.
|
|
642
726
|
*
|
|
@@ -645,7 +729,7 @@ declare const everySetValue: (values: ReadonlySet<unknown>, predicate: (value: u
|
|
|
645
729
|
* @param valuePredicate Predicate applied to each value.
|
|
646
730
|
* @returns Whether all keys and values satisfy their predicates.
|
|
647
731
|
*/
|
|
648
|
-
declare const everyMapEntry: (values: ReadonlyMap<unknown, unknown>, keyPredicate:
|
|
732
|
+
declare const everyMapEntry: (values: ReadonlyMap<unknown, unknown>, keyPredicate: BooleanPredicate<unknown>, valuePredicate: BooleanPredicate<unknown>) => boolean;
|
|
649
733
|
/**
|
|
650
734
|
* Checks whether every own enumerable string key/value pair satisfies the provided predicates.
|
|
651
735
|
*
|
|
@@ -654,7 +738,7 @@ declare const everyMapEntry: (values: ReadonlyMap<unknown, unknown>, keyPredicat
|
|
|
654
738
|
* @param valuePredicate Predicate applied to each corresponding value.
|
|
655
739
|
* @returns Whether all enumerable entries satisfy their predicates.
|
|
656
740
|
*/
|
|
657
|
-
declare const everyOwnEnumerableEntry: (values: Record<string, unknown>, keyPredicate:
|
|
741
|
+
declare const everyOwnEnumerableEntry: (values: Record<string, unknown>, keyPredicate: BooleanPredicate<string>, valuePredicate: BooleanPredicate<unknown>) => boolean;
|
|
658
742
|
|
|
659
743
|
/**
|
|
660
744
|
* Converts predicates to plain boolean predicates for iteration helpers.
|
|
@@ -664,4 +748,4 @@ declare const everyOwnEnumerableEntry: (values: Record<string, unknown>, keyPred
|
|
|
664
748
|
*/
|
|
665
749
|
declare const toBooleanPredicates: <A>(predicates: readonly ((value: A) => boolean)[]) => ReadonlyArray<(value: A) => boolean>;
|
|
666
750
|
|
|
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 };
|
|
751
|
+
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, isFile, isFiniteNumber, isFunction, isInfiniteNumber, isInstanceOf, isInteger, isIterable, isMap, isNaN, isNegative, isNil, 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
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* is-kit guard authoring guide:
|
|
3
|
+
* - Use define<T>(...) for reusable custom runtime checks.
|
|
4
|
+
* - Use and, andAll, or, and not to compose existing guards instead of
|
|
5
|
+
* hand-written boolean wrappers.
|
|
6
|
+
* - Use nullable, optional, or nullish to widen guards for nullish values.
|
|
7
|
+
* - Use struct or typedStruct for object-shape guards.
|
|
8
|
+
*/
|
|
1
9
|
type Predicate<T> = (value: unknown) => value is T;
|
|
2
10
|
type Refinement<A, B extends A> = (value: A) => value is B;
|
|
3
11
|
type Guard<T> = Predicate<T>;
|
|
@@ -69,12 +77,18 @@ declare function assert<A, B extends A>(refine: Refine<A, B>, value: A, message?
|
|
|
69
77
|
|
|
70
78
|
/**
|
|
71
79
|
* Wraps a user function as a typed predicate.
|
|
80
|
+
* Prefer `define<T>(...)` when creating a reusable custom guard from a runtime
|
|
81
|
+
* boolean check.
|
|
72
82
|
*
|
|
73
83
|
* Note: The correctness of the predicate is the caller's responsibility.
|
|
74
84
|
* Its result is coerced to a boolean using `!!` for consistent guard behavior.
|
|
75
85
|
*
|
|
76
86
|
* @param fn Function that returns truthy when the value matches the target shape.
|
|
77
87
|
* @returns Predicate narrowing to the intended type when it returns true.
|
|
88
|
+
* @example
|
|
89
|
+
* const isSlug = define<string>(
|
|
90
|
+
* (value) => isString(value) && /^[a-z0-9-]+$/.test(value)
|
|
91
|
+
* );
|
|
78
92
|
*/
|
|
79
93
|
declare function define<T>(fn: (value: unknown) => value is T): Predicate<T>;
|
|
80
94
|
declare function define<T>(fn: (value: unknown) => boolean): Predicate<T>;
|
|
@@ -146,49 +160,76 @@ declare function lazy<T>(factory: () => Predicate<T>): Predicate<T>;
|
|
|
146
160
|
|
|
147
161
|
/**
|
|
148
162
|
* Combines a precondition guard with an additional refinement to narrow the type.
|
|
163
|
+
* Prefer this over hand-written `precondition(x) && condition(x)` when the
|
|
164
|
+
* composed predicate should be reused as a guard.
|
|
149
165
|
*
|
|
150
166
|
* @param precondition Broad guard evaluated first; short-circuits on failure.
|
|
151
167
|
* @param condition Refinement evaluated only when `precondition` passes.
|
|
152
168
|
* @returns Predicate that narrows the input to a subtype.
|
|
169
|
+
* @example
|
|
170
|
+
* const isPositiveNumber = and(
|
|
171
|
+
* isNumber,
|
|
172
|
+
* predicateToRefine<number>((value) => value > 0)
|
|
173
|
+
* );
|
|
174
|
+
* @see andAll
|
|
153
175
|
*/
|
|
154
176
|
declare function and<A, B extends A>(precondition: Guard<A>, condition: Refine<A, B>): Predicate<B>;
|
|
155
177
|
/**
|
|
156
178
|
* Chains a sequence of refinements after a precondition, returning the final guard type.
|
|
179
|
+
* Use this instead of nested `&&` checks when each step should keep narrowing
|
|
180
|
+
* the next refinement.
|
|
157
181
|
*
|
|
158
182
|
* @param precondition Initial guard applied first.
|
|
159
183
|
* @param steps Subsequent refinements applied in order.
|
|
160
184
|
* @returns Guard reflecting the result of the refinement chain.
|
|
185
|
+
* @example
|
|
186
|
+
* const isPublicTitle = andAll(isString, minLength(4), startsWithPublic);
|
|
187
|
+
* @see and
|
|
161
188
|
*/
|
|
162
189
|
declare function andAll<A>(precondition: Guard<A>): Guard<A>;
|
|
163
190
|
declare function andAll<A, B extends A>(precondition: Guard<A>, step1: Refine<A, B>): Guard<B>;
|
|
164
191
|
declare function andAll<A, B extends A, C extends B>(precondition: Guard<A>, step1: Refine<A, B>, step2: Refine<B, C>): Guard<C>;
|
|
165
192
|
/**
|
|
166
193
|
* Logical OR over multiple guards.
|
|
194
|
+
* Prefer this over hand-written `guardA(x) || guardB(x)` when the composed
|
|
195
|
+
* predicate should be reused as a guard.
|
|
167
196
|
*
|
|
168
197
|
* @param guards Guards to evaluate; passes if any guard passes.
|
|
169
198
|
* @returns Guard for the union of all guarded types.
|
|
199
|
+
* @example
|
|
200
|
+
* const isId = or(isString, isNumber);
|
|
201
|
+
* @see oneOf
|
|
170
202
|
*/
|
|
171
203
|
declare function or<P extends readonly Guard<unknown>[]>(...guards: P): Guard<OutOfGuards<P>>;
|
|
172
204
|
/**
|
|
173
205
|
* Adapts a guard so it can be used as a refinement within a known supertype.
|
|
174
206
|
*
|
|
175
207
|
* @returns Function that converts a `Guard<T>` into a `Refine<A, T>` when `T extends A`.
|
|
208
|
+
* @see and
|
|
176
209
|
*/
|
|
177
210
|
declare function guardIn<A>(): <T extends A>(guard: Guard<T>) => Refine<A, T>;
|
|
178
211
|
/**
|
|
179
212
|
* Logical negation of a guard/refinement.
|
|
213
|
+
* Use this when a negated predicate should be named and reused.
|
|
180
214
|
*
|
|
181
215
|
* @param guard Guard or refinement to negate.
|
|
182
216
|
* @returns Refinement excluding the guarded subtype from the input type.
|
|
217
|
+
* @example
|
|
218
|
+
* const isPresent = not(isNil);
|
|
183
219
|
*/
|
|
184
220
|
declare function not<A, T>(guard: Guard<T>): Refine<A, Exclude<A, Extract<A, T>>>;
|
|
185
221
|
declare function not<A, B extends A>(refine: Refine<A, B>): Refine<A, Exclude<A, B>>;
|
|
186
222
|
|
|
187
223
|
/**
|
|
188
224
|
* Allows `null` in addition to values accepted by the given guard/refinement.
|
|
225
|
+
* Use this instead of hand-writing `value === null || guard(value)` when the
|
|
226
|
+
* widened predicate should stay reusable.
|
|
189
227
|
*
|
|
190
228
|
* @param guard Guard/refinement for the base type.
|
|
191
229
|
* @returns Guard/refinement widened to include `null`.
|
|
230
|
+
* @example
|
|
231
|
+
* const isNullableString = nullable(isString);
|
|
232
|
+
* @see nullish
|
|
192
233
|
*/
|
|
193
234
|
declare function nullable<T>(guard: Guard<T>): Guard<T | null>;
|
|
194
235
|
declare function nullable<A, B extends A>(refine: Refine<A, B>): Refine<A | null, B | null>;
|
|
@@ -197,22 +238,33 @@ declare function nullable<A, B extends A>(refine: Refine<A, B>): Refine<A | null
|
|
|
197
238
|
*
|
|
198
239
|
* @param guard Guard/refinement possibly including `null`.
|
|
199
240
|
* @returns Guard/refinement with `null` excluded.
|
|
241
|
+
* @example
|
|
242
|
+
* const isNonNullString = nonNull(nullable(isString));
|
|
200
243
|
*/
|
|
201
244
|
declare function nonNull<T>(guard: Guard<T>): Guard<Exclude<T, null>>;
|
|
202
245
|
declare function nonNull<A, B extends A>(refine: Refine<A, B>): Refine<Exclude<A, null>, Exclude<B, null>>;
|
|
203
246
|
/**
|
|
204
247
|
* Allows `null` or `undefined` in addition to values accepted by the guard.
|
|
248
|
+
* Use this instead of hand-writing `isNil(value) || guard(value)` when widening
|
|
249
|
+
* another guard.
|
|
205
250
|
*
|
|
206
251
|
* @param guard Guard/refinement for the base type.
|
|
207
252
|
* @returns Guard/refinement widened to include `null | undefined`.
|
|
253
|
+
* @example
|
|
254
|
+
* const isNullishString = nullish(isString);
|
|
255
|
+
* @see isNil
|
|
208
256
|
*/
|
|
209
257
|
declare function nullish<T>(guard: Guard<T>): Guard<T | null | undefined>;
|
|
210
258
|
declare function nullish<A, B extends A>(refine: Refine<A, B>): Refine<A | null | undefined, B | null | undefined>;
|
|
211
259
|
/**
|
|
212
260
|
* Allows `undefined` in addition to values accepted by the guard.
|
|
261
|
+
* Use this for value-level optionality. For optional object keys in `struct`,
|
|
262
|
+
* use `optionalKey(...)`.
|
|
213
263
|
*
|
|
214
264
|
* @param guard Guard/refinement for the base type.
|
|
215
265
|
* @returns Guard/refinement widened to include `undefined`.
|
|
266
|
+
* @example
|
|
267
|
+
* const isOptionalString = optional(isString);
|
|
216
268
|
*/
|
|
217
269
|
declare function optional<T>(guard: Guard<T>): Guard<T | undefined>;
|
|
218
270
|
declare function optional<A, B extends A>(refine: Refine<A, B>): Refine<A | undefined, B | undefined>;
|
|
@@ -221,6 +273,8 @@ declare function optional<A, B extends A>(refine: Refine<A, B>): Refine<A | unde
|
|
|
221
273
|
*
|
|
222
274
|
* @param guard Guard/refinement that may accept `undefined`.
|
|
223
275
|
* @returns Guard/refinement with `undefined` removed.
|
|
276
|
+
* @example
|
|
277
|
+
* const isRequiredString = required(optional(isString));
|
|
224
278
|
*/
|
|
225
279
|
declare function required<T>(guard: Guard<T | undefined>): Guard<T>;
|
|
226
280
|
declare function required<A, B extends A>(refine: Refine<A | undefined, B | undefined>): Refine<A, B>;
|
|
@@ -351,15 +405,38 @@ declare const isSymbol: Predicate<symbol>;
|
|
|
351
405
|
/**
|
|
352
406
|
* Checks whether a value is exactly `undefined`.
|
|
353
407
|
*
|
|
408
|
+
* For reusable nullish checks, use {@link isNil} or compose a named guard with
|
|
409
|
+
* {@link or} once and reuse it.
|
|
410
|
+
*
|
|
354
411
|
* @returns Predicate narrowing to `undefined`.
|
|
412
|
+
* @see isNil
|
|
355
413
|
*/
|
|
356
414
|
declare const isUndefined: Predicate<undefined>;
|
|
357
415
|
/**
|
|
358
416
|
* Checks whether a value is exactly `null`.
|
|
359
417
|
*
|
|
418
|
+
* For reusable nullish checks, use {@link isNil} or compose a named guard with
|
|
419
|
+
* {@link or} once and reuse it.
|
|
420
|
+
*
|
|
360
421
|
* @returns Predicate narrowing to `null`.
|
|
422
|
+
* @see isNil
|
|
361
423
|
*/
|
|
362
424
|
declare const isNull: Predicate<null>;
|
|
425
|
+
/**
|
|
426
|
+
* Checks whether a value is `null` or `undefined` (nullish).
|
|
427
|
+
*
|
|
428
|
+
* Prefer this over hand-rolling `isNull(x) || isUndefined(x)`: it is the same
|
|
429
|
+
* check expressed once. To widen an existing guard so it also accepts nullish
|
|
430
|
+
* values, use {@link nullish} instead.
|
|
431
|
+
*
|
|
432
|
+
* @returns Predicate narrowing to `null | undefined`.
|
|
433
|
+
* @example
|
|
434
|
+
* isNil(null); // true
|
|
435
|
+
* isNil(undefined); // true
|
|
436
|
+
* isNil(0); // false
|
|
437
|
+
* @see or
|
|
438
|
+
*/
|
|
439
|
+
declare const isNil: Guard<null | undefined>;
|
|
363
440
|
/**
|
|
364
441
|
* Checks whether a value is a JavaScript primitive.
|
|
365
442
|
*
|
|
@@ -485,6 +562,12 @@ declare const isURL: Guard<URL>;
|
|
|
485
562
|
* @returns Predicate narrowing to `Blob` when supported; otherwise always false.
|
|
486
563
|
*/
|
|
487
564
|
declare const isBlob: Guard<Blob>;
|
|
565
|
+
/**
|
|
566
|
+
* Checks whether a value is a `File` (in environments with File available).
|
|
567
|
+
*
|
|
568
|
+
* @returns Predicate narrowing to `File` when supported; otherwise always false.
|
|
569
|
+
*/
|
|
570
|
+
declare const isFile: Guard<File>;
|
|
488
571
|
/**
|
|
489
572
|
* Creates a guard that checks whether a value is an instance of `constructor`.
|
|
490
573
|
*
|
|
@@ -613,6 +696,7 @@ declare function tupleOf<const Fs extends readonly Predicate<unknown>[]>(...guar
|
|
|
613
696
|
readonly [K in keyof Fs]: GuardedOf<Fs[K]>;
|
|
614
697
|
}>;
|
|
615
698
|
|
|
699
|
+
type BooleanPredicate<T> = (value: T) => boolean;
|
|
616
700
|
/**
|
|
617
701
|
* Checks whether every array element satisfies the provided predicate.
|
|
618
702
|
*
|
|
@@ -620,7 +704,7 @@ declare function tupleOf<const Fs extends readonly Predicate<unknown>[]>(...guar
|
|
|
620
704
|
* @param predicate Predicate applied to each element.
|
|
621
705
|
* @returns Whether all elements satisfy `predicate`.
|
|
622
706
|
*/
|
|
623
|
-
declare const everyArrayValue: (values: readonly unknown[], predicate:
|
|
707
|
+
declare const everyArrayValue: (values: readonly unknown[], predicate: BooleanPredicate<unknown>) => boolean;
|
|
624
708
|
/**
|
|
625
709
|
* Checks whether a tuple matches the provided element predicates in order.
|
|
626
710
|
*
|
|
@@ -628,7 +712,7 @@ declare const everyArrayValue: (values: readonly unknown[], predicate: (value: u
|
|
|
628
712
|
* @param predicates Predicates aligned to each tuple index.
|
|
629
713
|
* @returns Whether lengths match and each index passes.
|
|
630
714
|
*/
|
|
631
|
-
declare const everyTupleValue: (values: readonly unknown[], predicates: readonly
|
|
715
|
+
declare const everyTupleValue: (values: readonly unknown[], predicates: readonly BooleanPredicate<unknown>[]) => boolean;
|
|
632
716
|
/**
|
|
633
717
|
* Checks whether every set value satisfies the provided predicate.
|
|
634
718
|
*
|
|
@@ -636,7 +720,7 @@ declare const everyTupleValue: (values: readonly unknown[], predicates: readonly
|
|
|
636
720
|
* @param predicate Predicate applied to each value.
|
|
637
721
|
* @returns Whether all set values satisfy `predicate`.
|
|
638
722
|
*/
|
|
639
|
-
declare const everySetValue: (values: ReadonlySet<unknown>, predicate:
|
|
723
|
+
declare const everySetValue: (values: ReadonlySet<unknown>, predicate: BooleanPredicate<unknown>) => boolean;
|
|
640
724
|
/**
|
|
641
725
|
* Checks whether every map entry satisfies the provided key and value predicates.
|
|
642
726
|
*
|
|
@@ -645,7 +729,7 @@ declare const everySetValue: (values: ReadonlySet<unknown>, predicate: (value: u
|
|
|
645
729
|
* @param valuePredicate Predicate applied to each value.
|
|
646
730
|
* @returns Whether all keys and values satisfy their predicates.
|
|
647
731
|
*/
|
|
648
|
-
declare const everyMapEntry: (values: ReadonlyMap<unknown, unknown>, keyPredicate:
|
|
732
|
+
declare const everyMapEntry: (values: ReadonlyMap<unknown, unknown>, keyPredicate: BooleanPredicate<unknown>, valuePredicate: BooleanPredicate<unknown>) => boolean;
|
|
649
733
|
/**
|
|
650
734
|
* Checks whether every own enumerable string key/value pair satisfies the provided predicates.
|
|
651
735
|
*
|
|
@@ -654,7 +738,7 @@ declare const everyMapEntry: (values: ReadonlyMap<unknown, unknown>, keyPredicat
|
|
|
654
738
|
* @param valuePredicate Predicate applied to each corresponding value.
|
|
655
739
|
* @returns Whether all enumerable entries satisfy their predicates.
|
|
656
740
|
*/
|
|
657
|
-
declare const everyOwnEnumerableEntry: (values: Record<string, unknown>, keyPredicate:
|
|
741
|
+
declare const everyOwnEnumerableEntry: (values: Record<string, unknown>, keyPredicate: BooleanPredicate<string>, valuePredicate: BooleanPredicate<unknown>) => boolean;
|
|
658
742
|
|
|
659
743
|
/**
|
|
660
744
|
* Converts predicates to plain boolean predicates for iteration helpers.
|
|
@@ -664,4 +748,4 @@ declare const everyOwnEnumerableEntry: (values: Record<string, unknown>, keyPred
|
|
|
664
748
|
*/
|
|
665
749
|
declare const toBooleanPredicates: <A>(predicates: readonly ((value: A) => boolean)[]) => ReadonlyArray<(value: A) => boolean>;
|
|
666
750
|
|
|
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 };
|
|
751
|
+
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, isFile, isFiniteNumber, isFunction, isInfiniteNumber, isInstanceOf, isInteger, isIterable, isMap, isNaN, isNegative, isNil, 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
|
@@ -45,6 +45,7 @@ __export(index_exports, {
|
|
|
45
45
|
isDataView: () => isDataView,
|
|
46
46
|
isDate: () => isDate,
|
|
47
47
|
isError: () => isError,
|
|
48
|
+
isFile: () => isFile,
|
|
48
49
|
isFiniteNumber: () => isFiniteNumber,
|
|
49
50
|
isFunction: () => isFunction,
|
|
50
51
|
isInfiniteNumber: () => isInfiniteNumber,
|
|
@@ -54,6 +55,7 @@ __export(index_exports, {
|
|
|
54
55
|
isMap: () => isMap,
|
|
55
56
|
isNaN: () => isNaN,
|
|
56
57
|
isNegative: () => isNegative,
|
|
58
|
+
isNil: () => isNil,
|
|
57
59
|
isNull: () => isNull,
|
|
58
60
|
isNumber: () => isNumber,
|
|
59
61
|
isNumberPrimitive: () => isNumberPrimitive,
|
|
@@ -112,6 +114,42 @@ function define(fn) {
|
|
|
112
114
|
return (value) => !!fn(value);
|
|
113
115
|
}
|
|
114
116
|
|
|
117
|
+
// src/utils/own-properties.ts
|
|
118
|
+
var hasOwnPropertyKey = (value, key) => Object.hasOwn(value, key);
|
|
119
|
+
var hasOwnPropertyKeys = (value, keys) => keys.every((key) => hasOwnPropertyKey(value, key));
|
|
120
|
+
|
|
121
|
+
// src/utils/guard-collections.ts
|
|
122
|
+
var everyIterableValue = (values, predicate) => {
|
|
123
|
+
for (const value of values) {
|
|
124
|
+
if (!predicate(value)) return false;
|
|
125
|
+
}
|
|
126
|
+
return true;
|
|
127
|
+
};
|
|
128
|
+
var everyKeyValueEntry = (entries, predicate) => {
|
|
129
|
+
for (const [key, value] of entries) {
|
|
130
|
+
if (!predicate(key, value)) return false;
|
|
131
|
+
}
|
|
132
|
+
return true;
|
|
133
|
+
};
|
|
134
|
+
var everyArrayValue = (values, predicate) => everyIterableValue(values, predicate);
|
|
135
|
+
var everyTupleValue = (values, predicates) => {
|
|
136
|
+
if (values.length !== predicates.length) return false;
|
|
137
|
+
for (let index = 0; index < predicates.length; index += 1) {
|
|
138
|
+
const predicate = predicates[index];
|
|
139
|
+
if (!predicate(values[index])) return false;
|
|
140
|
+
}
|
|
141
|
+
return true;
|
|
142
|
+
};
|
|
143
|
+
var everySetValue = (values, predicate) => everyIterableValue(values, predicate);
|
|
144
|
+
var everyMapEntry = (values, keyPredicate, valuePredicate) => everyKeyValueEntry(
|
|
145
|
+
values,
|
|
146
|
+
(key, value) => keyPredicate(key) && valuePredicate(value)
|
|
147
|
+
);
|
|
148
|
+
var everyOwnEnumerableEntry = (values, keyPredicate, valuePredicate) => everyIterableValue(
|
|
149
|
+
Object.keys(values),
|
|
150
|
+
(key) => keyPredicate(key) && valuePredicate(values[key])
|
|
151
|
+
);
|
|
152
|
+
|
|
115
153
|
// src/utils/object-tags.ts
|
|
116
154
|
var objectToString = Object.prototype.toString;
|
|
117
155
|
var OBJECT_TAG_DATE = "[object Date]";
|
|
@@ -125,6 +163,9 @@ var OBJECT_TAG_DATA_VIEW = "[object DataView]";
|
|
|
125
163
|
var OBJECT_TAG_ERROR = "[object Error]";
|
|
126
164
|
var getTag = (value) => objectToString.call(value);
|
|
127
165
|
|
|
166
|
+
// src/utils/to-boolean-predicates.ts
|
|
167
|
+
var toBooleanPredicates = (predicates) => predicates;
|
|
168
|
+
|
|
128
169
|
// src/core/object.ts
|
|
129
170
|
var defineTagGuard = (tag) => define((value) => getTag(value) === tag);
|
|
130
171
|
var defineOptionalInstanceGuard = (constructor) => constructor === void 0 ? define(() => false) : define(
|
|
@@ -177,6 +218,9 @@ var isURL = defineOptionalInstanceGuard(
|
|
|
177
218
|
var isBlob = defineOptionalInstanceGuard(
|
|
178
219
|
typeof Blob === "undefined" ? void 0 : Blob
|
|
179
220
|
);
|
|
221
|
+
var isFile = defineOptionalInstanceGuard(
|
|
222
|
+
typeof File === "undefined" ? void 0 : File
|
|
223
|
+
);
|
|
180
224
|
var isInstanceOf = (constructor) => define((value) => value instanceof constructor);
|
|
181
225
|
|
|
182
226
|
// src/core/equals.ts
|
|
@@ -197,19 +241,19 @@ function equalsBy(guard, selector) {
|
|
|
197
241
|
}
|
|
198
242
|
function equalsKey(key, target) {
|
|
199
243
|
const hasMatchingKey = define((input) => {
|
|
200
|
-
return isObject(input) &&
|
|
244
|
+
return isObject(input) && hasOwnPropertyKey(input, key) && Object.is(input[key], target);
|
|
201
245
|
});
|
|
202
246
|
return (input) => hasMatchingKey(input);
|
|
203
247
|
}
|
|
204
248
|
|
|
205
249
|
// src/core/key.ts
|
|
206
|
-
var hasKey = (key) => define((input) => isObject(input) &&
|
|
250
|
+
var hasKey = (key) => define((input) => isObject(input) && hasOwnPropertyKey(input, key));
|
|
207
251
|
var hasKeys = (...keys) => {
|
|
208
252
|
if (keys.length === 0) {
|
|
209
253
|
return define(() => false);
|
|
210
254
|
}
|
|
211
255
|
return define(
|
|
212
|
-
(input) => isObject(input) &&
|
|
256
|
+
(input) => isObject(input) && hasOwnPropertyKeys(input, keys)
|
|
213
257
|
);
|
|
214
258
|
};
|
|
215
259
|
function narrowKeyTo(guard, key) {
|
|
@@ -230,42 +274,6 @@ function lazy(factory) {
|
|
|
230
274
|
};
|
|
231
275
|
}
|
|
232
276
|
|
|
233
|
-
// src/utils/guard-collections.ts
|
|
234
|
-
var everyArrayValue = (values, predicate) => {
|
|
235
|
-
for (const value of values) {
|
|
236
|
-
if (!predicate(value)) return false;
|
|
237
|
-
}
|
|
238
|
-
return true;
|
|
239
|
-
};
|
|
240
|
-
var everyTupleValue = (values, predicates) => {
|
|
241
|
-
if (values.length !== predicates.length) return false;
|
|
242
|
-
for (const [index, predicate] of predicates.entries()) {
|
|
243
|
-
if (!predicate(values[index])) return false;
|
|
244
|
-
}
|
|
245
|
-
return true;
|
|
246
|
-
};
|
|
247
|
-
var everySetValue = (values, predicate) => {
|
|
248
|
-
for (const value of values) {
|
|
249
|
-
if (!predicate(value)) return false;
|
|
250
|
-
}
|
|
251
|
-
return true;
|
|
252
|
-
};
|
|
253
|
-
var everyMapEntry = (values, keyPredicate, valuePredicate) => {
|
|
254
|
-
for (const [key, value] of values) {
|
|
255
|
-
if (!keyPredicate(key) || !valuePredicate(value)) return false;
|
|
256
|
-
}
|
|
257
|
-
return true;
|
|
258
|
-
};
|
|
259
|
-
var everyOwnEnumerableEntry = (values, keyPredicate, valuePredicate) => {
|
|
260
|
-
for (const key of Object.keys(values)) {
|
|
261
|
-
if (!keyPredicate(key) || !valuePredicate(values[key])) return false;
|
|
262
|
-
}
|
|
263
|
-
return true;
|
|
264
|
-
};
|
|
265
|
-
|
|
266
|
-
// src/utils/to-boolean-predicates.ts
|
|
267
|
-
var toBooleanPredicates = (predicates) => predicates;
|
|
268
|
-
|
|
269
277
|
// src/core/logic.ts
|
|
270
278
|
function and(precondition, condition) {
|
|
271
279
|
return define((input) => {
|
|
@@ -372,6 +380,7 @@ var isBigInt = define((value) => typeof value === "bigint");
|
|
|
372
380
|
var isSymbol = define((value) => typeof value === "symbol");
|
|
373
381
|
var isUndefined = define((value) => value === void 0);
|
|
374
382
|
var isNull = define((value) => value === null);
|
|
383
|
+
var isNil = or(isNull, isUndefined);
|
|
375
384
|
var isPrimitive = or(
|
|
376
385
|
isString,
|
|
377
386
|
isNumberPrimitive,
|
|
@@ -464,12 +473,14 @@ var isOptionalSchemaField = define(
|
|
|
464
473
|
var hasRequiredKeys = (obj, entries) => (
|
|
465
474
|
// WHY: Required fields must be own properties; inherited values should not
|
|
466
475
|
// satisfy a schema because `struct` models object payload shape, not prototype chains.
|
|
467
|
-
entries.every(([key, guard]) =>
|
|
476
|
+
entries.every(([key, guard]) => hasOwnPropertyKey(obj, key) && guard(obj[key]))
|
|
468
477
|
);
|
|
469
478
|
var hasValidOptionalKeys = (obj, entries) => (
|
|
470
479
|
// WHY: Optional keys are validated only when present. Missing keys stay valid
|
|
471
480
|
// without forcing callers to encode `undefined` into the value guard.
|
|
472
|
-
entries.every(
|
|
481
|
+
entries.every(
|
|
482
|
+
([key, guard]) => !hasOwnPropertyKey(obj, key) || guard(obj[key])
|
|
483
|
+
)
|
|
473
484
|
);
|
|
474
485
|
var hasOnlyAllowedKeys = (obj, allowed) => Object.keys(obj).every((key) => allowed.has(key));
|
|
475
486
|
function optionalKey(guard) {
|
|
@@ -480,7 +491,7 @@ function struct(schema, options) {
|
|
|
480
491
|
const optionalEntries = [];
|
|
481
492
|
const schemaKeys = [];
|
|
482
493
|
for (const key in schema) {
|
|
483
|
-
if (!
|
|
494
|
+
if (!hasOwnPropertyKey(schema, key)) continue;
|
|
484
495
|
const field = schema[key];
|
|
485
496
|
schemaKeys.push(key);
|
|
486
497
|
if (isOptionalSchemaField(field)) {
|
|
@@ -542,6 +553,7 @@ function tupleOf(...guards) {
|
|
|
542
553
|
isDataView,
|
|
543
554
|
isDate,
|
|
544
555
|
isError,
|
|
556
|
+
isFile,
|
|
545
557
|
isFiniteNumber,
|
|
546
558
|
isFunction,
|
|
547
559
|
isInfiniteNumber,
|
|
@@ -551,6 +563,7 @@ function tupleOf(...guards) {
|
|
|
551
563
|
isMap,
|
|
552
564
|
isNaN,
|
|
553
565
|
isNegative,
|
|
566
|
+
isNil,
|
|
554
567
|
isNull,
|
|
555
568
|
isNumber,
|
|
556
569
|
isNumberPrimitive,
|
package/dist/index.mjs
CHANGED
|
@@ -10,6 +10,42 @@ function define(fn) {
|
|
|
10
10
|
return (value) => !!fn(value);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
// src/utils/own-properties.ts
|
|
14
|
+
var hasOwnPropertyKey = (value, key) => Object.hasOwn(value, key);
|
|
15
|
+
var hasOwnPropertyKeys = (value, keys) => keys.every((key) => hasOwnPropertyKey(value, key));
|
|
16
|
+
|
|
17
|
+
// src/utils/guard-collections.ts
|
|
18
|
+
var everyIterableValue = (values, predicate) => {
|
|
19
|
+
for (const value of values) {
|
|
20
|
+
if (!predicate(value)) return false;
|
|
21
|
+
}
|
|
22
|
+
return true;
|
|
23
|
+
};
|
|
24
|
+
var everyKeyValueEntry = (entries, predicate) => {
|
|
25
|
+
for (const [key, value] of entries) {
|
|
26
|
+
if (!predicate(key, value)) return false;
|
|
27
|
+
}
|
|
28
|
+
return true;
|
|
29
|
+
};
|
|
30
|
+
var everyArrayValue = (values, predicate) => everyIterableValue(values, predicate);
|
|
31
|
+
var everyTupleValue = (values, predicates) => {
|
|
32
|
+
if (values.length !== predicates.length) return false;
|
|
33
|
+
for (let index = 0; index < predicates.length; index += 1) {
|
|
34
|
+
const predicate = predicates[index];
|
|
35
|
+
if (!predicate(values[index])) return false;
|
|
36
|
+
}
|
|
37
|
+
return true;
|
|
38
|
+
};
|
|
39
|
+
var everySetValue = (values, predicate) => everyIterableValue(values, predicate);
|
|
40
|
+
var everyMapEntry = (values, keyPredicate, valuePredicate) => everyKeyValueEntry(
|
|
41
|
+
values,
|
|
42
|
+
(key, value) => keyPredicate(key) && valuePredicate(value)
|
|
43
|
+
);
|
|
44
|
+
var everyOwnEnumerableEntry = (values, keyPredicate, valuePredicate) => everyIterableValue(
|
|
45
|
+
Object.keys(values),
|
|
46
|
+
(key) => keyPredicate(key) && valuePredicate(values[key])
|
|
47
|
+
);
|
|
48
|
+
|
|
13
49
|
// src/utils/object-tags.ts
|
|
14
50
|
var objectToString = Object.prototype.toString;
|
|
15
51
|
var OBJECT_TAG_DATE = "[object Date]";
|
|
@@ -23,6 +59,9 @@ var OBJECT_TAG_DATA_VIEW = "[object DataView]";
|
|
|
23
59
|
var OBJECT_TAG_ERROR = "[object Error]";
|
|
24
60
|
var getTag = (value) => objectToString.call(value);
|
|
25
61
|
|
|
62
|
+
// src/utils/to-boolean-predicates.ts
|
|
63
|
+
var toBooleanPredicates = (predicates) => predicates;
|
|
64
|
+
|
|
26
65
|
// src/core/object.ts
|
|
27
66
|
var defineTagGuard = (tag) => define((value) => getTag(value) === tag);
|
|
28
67
|
var defineOptionalInstanceGuard = (constructor) => constructor === void 0 ? define(() => false) : define(
|
|
@@ -75,6 +114,9 @@ var isURL = defineOptionalInstanceGuard(
|
|
|
75
114
|
var isBlob = defineOptionalInstanceGuard(
|
|
76
115
|
typeof Blob === "undefined" ? void 0 : Blob
|
|
77
116
|
);
|
|
117
|
+
var isFile = defineOptionalInstanceGuard(
|
|
118
|
+
typeof File === "undefined" ? void 0 : File
|
|
119
|
+
);
|
|
78
120
|
var isInstanceOf = (constructor) => define((value) => value instanceof constructor);
|
|
79
121
|
|
|
80
122
|
// src/core/equals.ts
|
|
@@ -95,19 +137,19 @@ function equalsBy(guard, selector) {
|
|
|
95
137
|
}
|
|
96
138
|
function equalsKey(key, target) {
|
|
97
139
|
const hasMatchingKey = define((input) => {
|
|
98
|
-
return isObject(input) &&
|
|
140
|
+
return isObject(input) && hasOwnPropertyKey(input, key) && Object.is(input[key], target);
|
|
99
141
|
});
|
|
100
142
|
return (input) => hasMatchingKey(input);
|
|
101
143
|
}
|
|
102
144
|
|
|
103
145
|
// src/core/key.ts
|
|
104
|
-
var hasKey = (key) => define((input) => isObject(input) &&
|
|
146
|
+
var hasKey = (key) => define((input) => isObject(input) && hasOwnPropertyKey(input, key));
|
|
105
147
|
var hasKeys = (...keys) => {
|
|
106
148
|
if (keys.length === 0) {
|
|
107
149
|
return define(() => false);
|
|
108
150
|
}
|
|
109
151
|
return define(
|
|
110
|
-
(input) => isObject(input) &&
|
|
152
|
+
(input) => isObject(input) && hasOwnPropertyKeys(input, keys)
|
|
111
153
|
);
|
|
112
154
|
};
|
|
113
155
|
function narrowKeyTo(guard, key) {
|
|
@@ -128,42 +170,6 @@ function lazy(factory) {
|
|
|
128
170
|
};
|
|
129
171
|
}
|
|
130
172
|
|
|
131
|
-
// src/utils/guard-collections.ts
|
|
132
|
-
var everyArrayValue = (values, predicate) => {
|
|
133
|
-
for (const value of values) {
|
|
134
|
-
if (!predicate(value)) return false;
|
|
135
|
-
}
|
|
136
|
-
return true;
|
|
137
|
-
};
|
|
138
|
-
var everyTupleValue = (values, predicates) => {
|
|
139
|
-
if (values.length !== predicates.length) return false;
|
|
140
|
-
for (const [index, predicate] of predicates.entries()) {
|
|
141
|
-
if (!predicate(values[index])) return false;
|
|
142
|
-
}
|
|
143
|
-
return true;
|
|
144
|
-
};
|
|
145
|
-
var everySetValue = (values, predicate) => {
|
|
146
|
-
for (const value of values) {
|
|
147
|
-
if (!predicate(value)) return false;
|
|
148
|
-
}
|
|
149
|
-
return true;
|
|
150
|
-
};
|
|
151
|
-
var everyMapEntry = (values, keyPredicate, valuePredicate) => {
|
|
152
|
-
for (const [key, value] of values) {
|
|
153
|
-
if (!keyPredicate(key) || !valuePredicate(value)) return false;
|
|
154
|
-
}
|
|
155
|
-
return true;
|
|
156
|
-
};
|
|
157
|
-
var everyOwnEnumerableEntry = (values, keyPredicate, valuePredicate) => {
|
|
158
|
-
for (const key of Object.keys(values)) {
|
|
159
|
-
if (!keyPredicate(key) || !valuePredicate(values[key])) return false;
|
|
160
|
-
}
|
|
161
|
-
return true;
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
// src/utils/to-boolean-predicates.ts
|
|
165
|
-
var toBooleanPredicates = (predicates) => predicates;
|
|
166
|
-
|
|
167
173
|
// src/core/logic.ts
|
|
168
174
|
function and(precondition, condition) {
|
|
169
175
|
return define((input) => {
|
|
@@ -270,6 +276,7 @@ var isBigInt = define((value) => typeof value === "bigint");
|
|
|
270
276
|
var isSymbol = define((value) => typeof value === "symbol");
|
|
271
277
|
var isUndefined = define((value) => value === void 0);
|
|
272
278
|
var isNull = define((value) => value === null);
|
|
279
|
+
var isNil = or(isNull, isUndefined);
|
|
273
280
|
var isPrimitive = or(
|
|
274
281
|
isString,
|
|
275
282
|
isNumberPrimitive,
|
|
@@ -362,12 +369,14 @@ var isOptionalSchemaField = define(
|
|
|
362
369
|
var hasRequiredKeys = (obj, entries) => (
|
|
363
370
|
// WHY: Required fields must be own properties; inherited values should not
|
|
364
371
|
// satisfy a schema because `struct` models object payload shape, not prototype chains.
|
|
365
|
-
entries.every(([key, guard]) =>
|
|
372
|
+
entries.every(([key, guard]) => hasOwnPropertyKey(obj, key) && guard(obj[key]))
|
|
366
373
|
);
|
|
367
374
|
var hasValidOptionalKeys = (obj, entries) => (
|
|
368
375
|
// WHY: Optional keys are validated only when present. Missing keys stay valid
|
|
369
376
|
// without forcing callers to encode `undefined` into the value guard.
|
|
370
|
-
entries.every(
|
|
377
|
+
entries.every(
|
|
378
|
+
([key, guard]) => !hasOwnPropertyKey(obj, key) || guard(obj[key])
|
|
379
|
+
)
|
|
371
380
|
);
|
|
372
381
|
var hasOnlyAllowedKeys = (obj, allowed) => Object.keys(obj).every((key) => allowed.has(key));
|
|
373
382
|
function optionalKey(guard) {
|
|
@@ -378,7 +387,7 @@ function struct(schema, options) {
|
|
|
378
387
|
const optionalEntries = [];
|
|
379
388
|
const schemaKeys = [];
|
|
380
389
|
for (const key in schema) {
|
|
381
|
-
if (!
|
|
390
|
+
if (!hasOwnPropertyKey(schema, key)) continue;
|
|
382
391
|
const field = schema[key];
|
|
383
392
|
schemaKeys.push(key);
|
|
384
393
|
if (isOptionalSchemaField(field)) {
|
|
@@ -439,6 +448,7 @@ export {
|
|
|
439
448
|
isDataView,
|
|
440
449
|
isDate,
|
|
441
450
|
isError,
|
|
451
|
+
isFile,
|
|
442
452
|
isFiniteNumber,
|
|
443
453
|
isFunction,
|
|
444
454
|
isInfiniteNumber,
|
|
@@ -448,6 +458,7 @@ export {
|
|
|
448
458
|
isMap,
|
|
449
459
|
isNaN,
|
|
450
460
|
isNegative,
|
|
461
|
+
isNil,
|
|
451
462
|
isNull,
|
|
452
463
|
isNumber,
|
|
453
464
|
isNumberPrimitive,
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# is-kit docs
|
|
2
|
+
|
|
3
|
+
This directory contains the public documentation site for `is-kit`.
|
|
4
|
+
|
|
5
|
+
The site is built with Next.js and shadcn/ui. It serves the marketing pages, hand-written API guides, and the generated TypeDoc output.
|
|
6
|
+
|
|
7
|
+
## What lives here
|
|
8
|
+
|
|
9
|
+
- `app/` - Next.js routes and page entry points
|
|
10
|
+
- `components/` - reusable docs-site UI and page sections
|
|
11
|
+
- `constants/` - site navigation and page metadata
|
|
12
|
+
- `lib/` - docs-specific helpers and data shaping
|
|
13
|
+
- `public/` - static assets and generated API output
|
|
14
|
+
|
|
15
|
+
## Local development
|
|
16
|
+
|
|
17
|
+
From the repository root:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pnpm --filter ./docs dev
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Other common commands:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pnpm --filter ./docs build
|
|
27
|
+
pnpm --filter ./docs start
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
If you use `mise`, run the same commands through `mise exec`.
|
|
31
|
+
|
|
32
|
+
## Generated API reference
|
|
33
|
+
|
|
34
|
+
The API reference is generated from the library source with TypeDoc and written to `docs/public/api`.
|
|
35
|
+
|
|
36
|
+
From the repository root:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pnpm typedoc
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
After generation, the docs site serves that static output under `/api`.
|
|
43
|
+
|
|
44
|
+
## Common editing workflow
|
|
45
|
+
|
|
46
|
+
### Update a guide or landing page
|
|
47
|
+
|
|
48
|
+
Edit the relevant route in `app/` and the supporting components in `components/`.
|
|
49
|
+
|
|
50
|
+
### Update navigation or docs metadata
|
|
51
|
+
|
|
52
|
+
Check the files under `constants/` and `lib/`.
|
|
53
|
+
|
|
54
|
+
### Refresh generated API docs
|
|
55
|
+
|
|
56
|
+
Run:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
pnpm typedoc
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Add or update static assets
|
|
63
|
+
|
|
64
|
+
Place them under `public/`.
|
|
65
|
+
|
|
66
|
+
## shadcn/ui
|
|
67
|
+
|
|
68
|
+
The docs app is already configured for shadcn/ui with the `@/*` alias.
|
|
69
|
+
|
|
70
|
+
List available components:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pnpm --filter ./docs run shadcn:list
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Add a component:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
pnpm --filter ./docs run shadcn:add button
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
If you need to reinitialize shadcn:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
pnpm --filter ./docs run shadcn:init
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Example
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
import { Button } from '@/components/ui/button';
|
|
92
|
+
|
|
93
|
+
export default function Example() {
|
|
94
|
+
return (
|
|
95
|
+
<div className='space-x-2'>
|
|
96
|
+
<Button>Default</Button>
|
|
97
|
+
<Button variant='secondary'>Secondary</Button>
|
|
98
|
+
</div>
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
```
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# is-kit Agent Rules
|
|
2
|
+
|
|
3
|
+
Copy this into a consumer repository's `AGENTS.md`, `CLAUDE.md`, or
|
|
4
|
+
`.agents/rules/is-kit.md` when AI agents generate or review code that uses
|
|
5
|
+
`is-kit`.
|
|
6
|
+
|
|
7
|
+
## Usage Rules
|
|
8
|
+
|
|
9
|
+
- Build reusable custom guards with `define<T>(...)` instead of writing
|
|
10
|
+
standalone type-predicate functions by hand.
|
|
11
|
+
- Prefer `is-kit` combinators over hand-written boolean composition when
|
|
12
|
+
combining existing guards.
|
|
13
|
+
- Use `or(isA, isB)` instead of `(value) => isA(value) || isB(value)` when the
|
|
14
|
+
result should be a reusable guard.
|
|
15
|
+
- Use `and(baseGuard, refinement)` or `andAll(...)` instead of hand-written
|
|
16
|
+
`&&` checks when narrowing should be preserved.
|
|
17
|
+
- Use `not(guard)` for reusable negated guards.
|
|
18
|
+
- Use `nullable(guard)`, `optional(guard)`, or `nullish(guard)` when widening an
|
|
19
|
+
existing guard to accept `null` and/or `undefined`.
|
|
20
|
+
- Use `isNil(value)` when checking a value directly for `null | undefined`.
|
|
21
|
+
- Use `optionalKey(guard)` for optional object keys inside `struct`.
|
|
22
|
+
|
|
23
|
+
## Preferred Examples
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import {
|
|
27
|
+
and,
|
|
28
|
+
define,
|
|
29
|
+
isNil,
|
|
30
|
+
isNumber,
|
|
31
|
+
isString,
|
|
32
|
+
nullish,
|
|
33
|
+
or,
|
|
34
|
+
predicateToRefine
|
|
35
|
+
} from 'is-kit';
|
|
36
|
+
|
|
37
|
+
const isId = or(isString, isNumber);
|
|
38
|
+
const isMaybeName = nullish(isString);
|
|
39
|
+
const isSlug = define<string>(
|
|
40
|
+
(value) => isString(value) && /^[a-z0-9-]+$/.test(value)
|
|
41
|
+
);
|
|
42
|
+
const isPositiveNumber = and(
|
|
43
|
+
isNumber,
|
|
44
|
+
predicateToRefine<number>((value) => value > 0)
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
declare const value: unknown;
|
|
48
|
+
|
|
49
|
+
if (isNil(value)) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Avoid
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
declare const value: unknown;
|
|
58
|
+
|
|
59
|
+
const isId = (value: unknown) => isString(value) || isNumber(value);
|
|
60
|
+
const isMaybeName = (value: unknown) => value == null || isString(value);
|
|
61
|
+
const isSlug = (value: unknown): value is string =>
|
|
62
|
+
isString(value) && /^[a-z0-9-]+$/.test(value);
|
|
63
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "is-kit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.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",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
],
|
|
23
23
|
"files": [
|
|
24
24
|
"dist",
|
|
25
|
+
"docs/agent-rules.md",
|
|
25
26
|
"README.md",
|
|
26
27
|
"LICENSE"
|
|
27
28
|
],
|