@satoshibits/functional 1.0.2

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.
Files changed (46) hide show
  1. package/README.md +242 -0
  2. package/dist/array-utils.d.mts +317 -0
  3. package/dist/array-utils.d.mts.map +1 -0
  4. package/dist/array-utils.mjs +370 -0
  5. package/dist/array-utils.mjs.map +1 -0
  6. package/dist/composition.d.mts +603 -0
  7. package/dist/composition.d.mts.map +1 -0
  8. package/dist/composition.mjs +516 -0
  9. package/dist/composition.mjs.map +1 -0
  10. package/dist/object-utils.d.mts +267 -0
  11. package/dist/object-utils.d.mts.map +1 -0
  12. package/dist/object-utils.mjs +258 -0
  13. package/dist/object-utils.mjs.map +1 -0
  14. package/dist/option.d.mts +622 -0
  15. package/dist/option.d.mts.map +1 -0
  16. package/dist/option.mjs +637 -0
  17. package/dist/option.mjs.map +1 -0
  18. package/dist/performance.d.mts +265 -0
  19. package/dist/performance.d.mts.map +1 -0
  20. package/dist/performance.mjs +453 -0
  21. package/dist/performance.mjs.map +1 -0
  22. package/dist/pipeline.d.mts +431 -0
  23. package/dist/pipeline.d.mts.map +1 -0
  24. package/dist/pipeline.mjs +460 -0
  25. package/dist/pipeline.mjs.map +1 -0
  26. package/dist/predicates.d.mts +722 -0
  27. package/dist/predicates.d.mts.map +1 -0
  28. package/dist/predicates.mjs +802 -0
  29. package/dist/predicates.mjs.map +1 -0
  30. package/dist/reader-result.d.mts +422 -0
  31. package/dist/reader-result.d.mts.map +1 -0
  32. package/dist/reader-result.mjs +758 -0
  33. package/dist/reader-result.mjs.map +1 -0
  34. package/dist/result.d.mts +684 -0
  35. package/dist/result.d.mts.map +1 -0
  36. package/dist/result.mjs +814 -0
  37. package/dist/result.mjs.map +1 -0
  38. package/dist/types.d.mts +439 -0
  39. package/dist/types.d.mts.map +1 -0
  40. package/dist/types.mjs +191 -0
  41. package/dist/types.mjs.map +1 -0
  42. package/dist/validation.d.mts +622 -0
  43. package/dist/validation.d.mts.map +1 -0
  44. package/dist/validation.mjs +852 -0
  45. package/dist/validation.mjs.map +1 -0
  46. package/package.json +46 -0
@@ -0,0 +1,722 @@
1
+ /**
2
+ * @module predicates
3
+ * @description Functional utilities for composing and manipulating predicate functions.
4
+ * Predicates are functions that return boolean values and are fundamental
5
+ * for filtering, validation, and conditional logic. This module provides
6
+ * combinators for building complex predicates from simple ones, along with
7
+ * common predicate patterns for everyday use.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { and, or, not, isNotNil, inRange, hasProperty } from './predicates.mts';
12
+ *
13
+ * // compose predicates with logical operators
14
+ * const isPositiveEven = and(
15
+ * (n: number) => n > 0,
16
+ * (n: number) => n % 2 === 0
17
+ * );
18
+ *
19
+ * // create reusable validation functions
20
+ * const isValidUser = and(
21
+ * hasProperty('email'),
22
+ * hasProperty('name'),
23
+ * user => isNotNil(user.email) && user.email.includes('@')
24
+ * );
25
+ *
26
+ * // filter collections
27
+ * const validUsers = users.filter(isValidUser);
28
+ * const adults = people.filter(person => inRange(18, 120)(person.age));
29
+ * ```
30
+ *
31
+ * @category Core
32
+ * @since 2025-07-03
33
+ */
34
+ /**
35
+ * Logical AND combinator for predicates.
36
+ * @description Returns true only if all predicates return true. Short-circuits
37
+ * on the first false result for efficiency. Accepts any number of predicates
38
+ * and combines them into a single predicate function.
39
+ *
40
+ * @template T - The type of value being tested
41
+ * @param {Array<(value: T) => boolean>} predicates - Functions to combine with AND logic
42
+ * @returns {(value: T) => boolean} A predicate that returns true if all predicates pass
43
+ *
44
+ * @category Combinators
45
+ * @example
46
+ * // Basic number validation
47
+ * const isPositive = (n: number) => n > 0;
48
+ * const isEven = (n: number) => n % 2 === 0;
49
+ * const isPositiveEven = and(isPositive, isEven);
50
+ *
51
+ * isPositiveEven(4); // => true
52
+ * isPositiveEven(-2); // => false (not positive)
53
+ * isPositiveEven(3); // => false (not even)
54
+ *
55
+ * @example
56
+ * // Validating user data
57
+ * const hasName = (user: { name?: string }) => !!user.name;
58
+ * const hasEmail = (user: { email?: string }) => !!user.email;
59
+ * const isAdult = (user: { age?: number }) => (user.age ?? 0) >= 18;
60
+ *
61
+ * const isValidAdultUser = and(hasName, hasEmail, isAdult);
62
+ * isValidAdultUser({ name: 'John', email: 'john@example.com', age: 25 }); // => true
63
+ *
64
+ * @example
65
+ * // Form validation with multiple rules
66
+ * const isValidPassword = and(
67
+ * (pwd: string) => pwd.length >= 8,
68
+ * (pwd: string) => /[A-Z]/.test(pwd),
69
+ * (pwd: string) => /[0-9]/.test(pwd),
70
+ * (pwd: string) => /[!@#$%^&*]/.test(pwd)
71
+ * );
72
+ *
73
+ * isValidPassword('Pass123!'); // => true
74
+ * isValidPassword('weak'); // => false
75
+ *
76
+ * @see or - Logical OR combinator
77
+ * @see not - Logical NOT combinator
78
+ * @since 2025-07-03
79
+ */
80
+ export declare const and: <T>(...predicates: ((value: T) => boolean)[]) => (value: T) => boolean;
81
+ /**
82
+ * Logical OR combinator for predicates.
83
+ * @description Returns true if at least one predicate returns true. Short-circuits
84
+ * on the first true result for efficiency. Accepts any number of predicates
85
+ * and combines them into a single predicate function.
86
+ *
87
+ * @template T - The type of value being tested
88
+ * @param {Array<(value: T) => boolean>} predicates - Functions to combine with OR logic
89
+ * @returns {(value: T) => boolean} A predicate that returns true if any predicate passes
90
+ *
91
+ * @category Combinators
92
+ * @example
93
+ * // Role-based access control
94
+ * const isAdmin = (user: { role: string }) => user.role === 'admin';
95
+ * const isModerator = (user: { role: string }) => user.role === 'moderator';
96
+ * const hasPrivileges = or(isAdmin, isModerator);
97
+ *
98
+ * hasPrivileges({ role: 'admin' }); // => true
99
+ * hasPrivileges({ role: 'moderator' }); // => true
100
+ * hasPrivileges({ role: 'user' }); // => false
101
+ *
102
+ * @example
103
+ * // Multiple payment methods
104
+ * const hasCreditCard = (payment: { type: string }) => payment.type === 'credit';
105
+ * const hasPayPal = (payment: { type: string }) => payment.type === 'paypal';
106
+ * const hasCrypto = (payment: { type: string }) => payment.type === 'crypto';
107
+ *
108
+ * const acceptsPayment = or(hasCreditCard, hasPayPal, hasCrypto);
109
+ * acceptsPayment({ type: 'paypal' }); // => true
110
+ *
111
+ * @example
112
+ * // Flexible search criteria
113
+ * const searchTerm = 'john';
114
+ * const matchesSearch = or(
115
+ * (user: User) => user.name.toLowerCase().includes(searchTerm),
116
+ * (user: User) => user.email.toLowerCase().includes(searchTerm),
117
+ * (user: User) => user.username.toLowerCase().includes(searchTerm)
118
+ * );
119
+ *
120
+ * const searchResults = users.filter(matchesSearch);
121
+ *
122
+ * @see and - Logical AND combinator
123
+ * @see not - Logical NOT combinator
124
+ * @since 2025-07-03
125
+ */
126
+ export declare const or: <T>(...predicates: ((value: T) => boolean)[]) => (value: T) => boolean;
127
+ /**
128
+ * Logical NOT combinator for predicates.
129
+ * @description Inverts the result of a predicate, turning true to false and
130
+ * false to true. Useful for creating the opposite of existing predicates
131
+ * without duplicating logic.
132
+ *
133
+ * @template T - The type of value being tested
134
+ * @param {(value: T) => boolean} predicate - The predicate to invert
135
+ * @returns {(value: T) => boolean} A predicate that returns the opposite result
136
+ *
137
+ * @category Combinators
138
+ * @example
139
+ * // Basic negation
140
+ * const isPositive = (n: number) => n > 0;
141
+ * const isNegativeOrZero = not(isPositive);
142
+ *
143
+ * isNegativeOrZero(-5); // => true
144
+ * isNegativeOrZero(0); // => true
145
+ * isNegativeOrZero(5); // => false
146
+ *
147
+ * @example
148
+ * // Filtering out specific items
149
+ * const isError = (log: { level: string }) => log.level === 'error';
150
+ * const nonErrorLogs = logs.filter(not(isError));
151
+ *
152
+ * @example
153
+ * // Excluding items from selection
154
+ * const isBlacklisted = oneOf(blacklistedIds);
155
+ * const allowedItems = items.filter(not(item => isBlacklisted(item.id)));
156
+ *
157
+ * @see and - Logical AND combinator
158
+ * @see or - Logical OR combinator
159
+ * @since 2025-07-03
160
+ */
161
+ export declare const not: <T>(predicate: (value: T) => boolean) => (value: T) => boolean;
162
+ /**
163
+ * Exclusive OR (XOR) combinator for predicates.
164
+ * @description Returns true if exactly one predicate returns true, but not both.
165
+ * Useful for ensuring mutually exclusive conditions or validating that
166
+ * exactly one option is selected from a pair.
167
+ *
168
+ * @template T - The type of value being tested
169
+ * @param {(value: T) => boolean} predicate1 - First predicate to test
170
+ * @param {(value: T) => boolean} predicate2 - Second predicate to test
171
+ * @returns {(value: T) => boolean} A predicate that returns true if exactly one input predicate passes
172
+ *
173
+ * @category Combinators
174
+ * @example
175
+ * // Authentication method validation
176
+ * const hasUsername = (auth: { username?: string }) => !!auth.username;
177
+ * const hasEmail = (auth: { email?: string }) => !!auth.email;
178
+ * const hasExactlyOneIdentifier = xor(hasUsername, hasEmail);
179
+ *
180
+ * hasExactlyOneIdentifier({ username: 'john' }); // => true
181
+ * hasExactlyOneIdentifier({ email: 'john@example.com' }); // => true
182
+ * hasExactlyOneIdentifier({ username: 'john', email: 'j@e.com' }); // => false
183
+ * hasExactlyOneIdentifier({}); // => false
184
+ *
185
+ * @example
186
+ * // Toggle state validation
187
+ * const isManualMode = (config: Config) => config.mode === 'manual';
188
+ * const hasAutoSettings = (config: Config) => !!config.autoSettings;
189
+ * const isValidConfig = xor(isManualMode, hasAutoSettings);
190
+ * // Ensures either manual mode OR auto settings, but not both
191
+ *
192
+ * @see and - Logical AND combinator
193
+ * @see or - Logical OR combinator
194
+ * @since 2025-07-03
195
+ */
196
+ export declare const xor: <T>(predicate1: (value: T) => boolean, predicate2: (value: T) => boolean) => (value: T) => boolean;
197
+ /**
198
+ * Creates a predicate that checks if a value is not null or undefined.
199
+ * @description Type guard function that narrows types by excluding null and undefined.
200
+ * Particularly useful for filtering arrays and conditional type narrowing.
201
+ * Unlike truthiness checks, this explicitly checks for null/undefined only.
202
+ *
203
+ * @template T - The type of the non-null value
204
+ * @param {T | null | undefined} value - The value to check
205
+ * @returns {value is T} True if the value is not null or undefined
206
+ *
207
+ * @category Type Guards
208
+ * @example
209
+ * // Array filtering with type narrowing
210
+ * const values: (string | null | undefined)[] = ['a', null, 'b', undefined, 'c'];
211
+ * const nonNullValues = values.filter(isNotNil);
212
+ * // => ['a', 'b', 'c'] with type string[]
213
+ *
214
+ * @example
215
+ * // Type guard in conditional
216
+ * function processValue(value: string | null) {
217
+ * if (isNotNil(value)) {
218
+ * // TypeScript knows value is string here
219
+ * return value.toUpperCase();
220
+ * }
221
+ * return 'DEFAULT';
222
+ * }
223
+ *
224
+ * @example
225
+ * // Optional chaining alternative
226
+ * const users: (User | null)[] = await fetchUsers();
227
+ * const activeUsers = users
228
+ * .filter(isNotNil)
229
+ * .filter(user => user.status === 'active');
230
+ *
231
+ * @see isNil - Check if value is null or undefined
232
+ * @see isEmpty - Check if value is empty
233
+ * @since 2025-07-03
234
+ */
235
+ export declare const isNotNil: <T>(value: T | null | undefined) => value is T;
236
+ /**
237
+ * Creates a predicate that checks if a value is null or undefined.
238
+ * @description Type guard function that identifies null and undefined values.
239
+ * Useful for validation, error handling, and conditional logic where
240
+ * null/undefined values need special treatment.
241
+ *
242
+ * @template T - The type of the value when not null/undefined
243
+ * @param {T | null | undefined} value - The value to check
244
+ * @returns {value is null | undefined} True if the value is null or undefined
245
+ *
246
+ * @category Type Guards
247
+ * @example
248
+ * // Filtering null/undefined values
249
+ * const values = [1, null, 2, undefined, 3];
250
+ * const nilValues = values.filter(isNil);
251
+ * // => [null, undefined]
252
+ *
253
+ * @example
254
+ * // Early return pattern
255
+ * function processUser(user: User | null) {
256
+ * if (isNil(user)) {
257
+ * return { error: 'User not found' };
258
+ * }
259
+ * // Process user...
260
+ * }
261
+ *
262
+ * @example
263
+ * // Default value handling
264
+ * function getConfig(key: string): string {
265
+ * const value = configMap.get(key);
266
+ * if (isNil(value)) {
267
+ * return getDefaultConfig(key);
268
+ * }
269
+ * return value;
270
+ * }
271
+ *
272
+ * @see isNotNil - Check if value is not null or undefined
273
+ * @see isEmpty - Check if value is empty
274
+ * @since 2025-07-03
275
+ */
276
+ export declare const isNil: <T>(value: T | null | undefined) => value is null | undefined;
277
+ /**
278
+ * Checks if a value is empty (null, undefined, empty string, empty array, or empty object).
279
+ * @description Comprehensive emptiness check that handles multiple data types.
280
+ * Returns true for null, undefined, empty strings, arrays with no elements,
281
+ * and objects with no own properties. Does not consider whitespace-only strings as empty.
282
+ *
283
+ * @param {unknown} value - The value to check for emptiness
284
+ * @returns {boolean} True if the value is considered empty
285
+ *
286
+ * @category Value Checks
287
+ * @example
288
+ * // Basic emptiness checks
289
+ * isEmpty(null); // => true
290
+ * isEmpty(undefined); // => true
291
+ * isEmpty(''); // => true
292
+ * isEmpty([]); // => true
293
+ * isEmpty({}); // => true
294
+ * isEmpty('hello'); // => false
295
+ * isEmpty([1, 2, 3]); // => false
296
+ * isEmpty({ a: 1 }); // => false
297
+ *
298
+ * @example
299
+ * // Form validation
300
+ * const formData = { name: '', email: 'test@example.com', bio: null };
301
+ * const emptyFields = Object.entries(formData)
302
+ * .filter(([_, value]) => isEmpty(value))
303
+ * .map(([key]) => key);
304
+ * // => ['name', 'bio']
305
+ *
306
+ * @example
307
+ * // API response validation
308
+ * function handleResponse(data: unknown) {
309
+ * if (isEmpty(data)) {
310
+ * throw new Error('Empty response received');
311
+ * }
312
+ * return processData(data);
313
+ * }
314
+ *
315
+ * @see isNotEmpty - Check if value has content
316
+ * @see isNil - Check if value is null or undefined
317
+ * @since 2025-07-03
318
+ */
319
+ export declare const isEmpty: (value: unknown) => boolean;
320
+ /**
321
+ * Opposite of isEmpty - checks if a value has content.
322
+ * @description Returns true if a value is not empty. A value is considered
323
+ * to have content if it's not null, undefined, an empty string, an empty array,
324
+ * or an empty object.
325
+ *
326
+ * @param {unknown} value - The value to check for content
327
+ * @returns {boolean} True if the value has content
328
+ *
329
+ * @category Value Checks
330
+ * @example
331
+ * // Form field validation
332
+ * const requiredFields = ['name', 'email'];
333
+ * const formData = { name: 'John', email: '', phone: '123' };
334
+ *
335
+ * const filledRequired = requiredFields.every(field =>
336
+ * isNotEmpty(formData[field as keyof typeof formData])
337
+ * );
338
+ * // => false (email is empty)
339
+ *
340
+ * @example
341
+ * // Filter out empty values
342
+ * const config = {
343
+ * apiKey: 'abc123',
344
+ * endpoint: '',
345
+ * timeout: 5000,
346
+ * headers: {}
347
+ * };
348
+ *
349
+ * const validConfig = Object.fromEntries(
350
+ * Object.entries(config).filter(([_, value]) => isNotEmpty(value))
351
+ * );
352
+ * // => { apiKey: 'abc123', timeout: 5000 }
353
+ *
354
+ * @see isEmpty - Check if value is empty
355
+ * @see isNotNil - Check if value is not null or undefined
356
+ * @since 2025-07-03
357
+ */
358
+ export declare const isNotEmpty: (value: unknown) => boolean;
359
+ /**
360
+ * Creates a predicate that checks if a value equals a specific value.
361
+ * @description Uses strict equality (===) to compare values. Creates a reusable
362
+ * predicate function that can be used for filtering, finding, or validation.
363
+ *
364
+ * @template T - The type of values being compared
365
+ * @param {T} target - The value to compare against
366
+ * @returns {(value: T) => boolean} A predicate that returns true if the value equals the target
367
+ *
368
+ * @category Comparison
369
+ * @example
370
+ * // Basic filtering
371
+ * const isJohn = equals('John');
372
+ * ['John', 'Jane', 'John', 'Jack'].filter(isJohn);
373
+ * // => ['John', 'John']
374
+ *
375
+ * @example
376
+ * // Status checking
377
+ * const isActive = equals('active');
378
+ * const activeUsers = users.filter(user => isActive(user.status));
379
+ *
380
+ * @example
381
+ * // Finding specific items
382
+ * const isTargetId = equals(targetUserId);
383
+ * const targetUser = users.find(user => isTargetId(user.id));
384
+ *
385
+ * @see oneOf - Check if value is one of multiple values
386
+ * @since 2025-07-03
387
+ */
388
+ export declare const equals: <T>(target: T) => (value: T) => boolean;
389
+ /**
390
+ * Creates a predicate that checks if a value is one of the specified values.
391
+ * @description Uses Array.includes internally to check membership. Useful for
392
+ * creating allowlists, checking against enums, or validating against a set
393
+ * of acceptable values.
394
+ *
395
+ * @template T - The type of values in the options array
396
+ * @param {T[]} options - Array of acceptable values
397
+ * @returns {(value: T) => boolean} A predicate that returns true if the value is in the options
398
+ *
399
+ * @category Comparison
400
+ * @example
401
+ * // Day type checking
402
+ * const isWeekend = oneOf(['Saturday', 'Sunday']);
403
+ * isWeekend('Saturday'); // => true
404
+ * isWeekend('Monday'); // => false
405
+ *
406
+ * @example
407
+ * // Permission checking
408
+ * const canEdit = oneOf(['admin', 'editor', 'author']);
409
+ * const editableContent = content.filter(item => canEdit(item.userRole));
410
+ *
411
+ * @example
412
+ * // Enum validation
413
+ * enum Status { Active = 'active', Inactive = 'inactive', Pending = 'pending' }
414
+ * const isValidStatus = oneOf(Object.values(Status));
415
+ *
416
+ * @see equals - Check if value equals a specific value
417
+ * @see includes - Check if array includes a value
418
+ * @since 2025-07-03
419
+ */
420
+ export declare const oneOf: <T>(options: T[]) => (value: T) => boolean;
421
+ /**
422
+ * Creates a predicate that checks if a number is within a range (inclusive).
423
+ * @description Both minimum and maximum values are included in the range.
424
+ * Useful for validating numeric values against acceptable bounds.
425
+ *
426
+ * @param {number} min - The minimum value (inclusive)
427
+ * @param {number} max - The maximum value (inclusive)
428
+ * @returns {(value: number) => boolean} A predicate that returns true if the value is within range
429
+ *
430
+ * @category Numeric
431
+ * @example
432
+ * // Age validation
433
+ * const isValidAge = inRange(18, 65);
434
+ * isValidAge(17); // => false
435
+ * isValidAge(18); // => true
436
+ * isValidAge(30); // => true
437
+ * isValidAge(65); // => true
438
+ * isValidAge(66); // => false
439
+ *
440
+ * @example
441
+ * // Score validation
442
+ * const isPassingGrade = inRange(60, 100);
443
+ * const passingStudents = students.filter(s => isPassingGrade(s.score));
444
+ *
445
+ * @example
446
+ * // Temperature monitoring
447
+ * const isNormalTemp = inRange(36.0, 37.5);
448
+ * const alerts = readings
449
+ * .filter(not(r => isNormalTemp(r.temperature)))
450
+ * .map(r => ({ time: r.time, temp: r.temperature }));
451
+ *
452
+ * @since 2025-07-03
453
+ */
454
+ export declare const inRange: (min: number, max: number) => (value: number) => boolean;
455
+ /**
456
+ * Creates a predicate that checks if a string matches a regular expression.
457
+ * @description Uses RegExp.test() to check if the pattern matches the string.
458
+ * The regular expression can include flags for case-insensitive matching,
459
+ * multiline mode, etc.
460
+ *
461
+ * @param {RegExp} pattern - The regular expression to test against
462
+ * @returns {(value: string) => boolean} A predicate that returns true if the string matches
463
+ *
464
+ * @category String
465
+ * @example
466
+ * // Email validation
467
+ * const isEmail = matches(/^[^\s@]+@[^\s@]+\.[^\s@]+$/);
468
+ * isEmail('test@example.com'); // => true
469
+ * isEmail('invalid-email'); // => false
470
+ *
471
+ * @example
472
+ * // Phone number validation
473
+ * const isPhoneNumber = matches(/^\+?[\d\s-()]+$/);
474
+ * const validPhones = contacts
475
+ * .map(c => c.phone)
476
+ * .filter(isPhoneNumber);
477
+ *
478
+ * @example
479
+ * // URL validation with flags
480
+ * const isHttpUrl = matches(/^https?:\/\//i);
481
+ * const secureUrls = urls.filter(matches(/^https:\/\//));
482
+ *
483
+ * @since 2025-07-03
484
+ */
485
+ export declare const matches: (pattern: RegExp) => (value: string) => boolean;
486
+ /**
487
+ * Creates a predicate that checks if an object has a specific property.
488
+ * @description Type guard that checks for property existence using the 'in' operator.
489
+ * The returned predicate narrows the type to include the checked property.
490
+ * Works with string, number, and symbol keys.
491
+ *
492
+ * @template K - The type of the property key
493
+ * @param {K} key - The property key to check for
494
+ * @returns {<T extends object>(obj: T) => obj is T & Record<K, unknown>} A type guard predicate
495
+ *
496
+ * @category Object
497
+ * @example
498
+ * // Type-safe property filtering
499
+ * const hasEmail = hasProperty('email');
500
+ * const users = [
501
+ * { name: 'John', email: 'john@example.com' },
502
+ * { name: 'Jane' }
503
+ * ];
504
+ * const usersWithEmail = users.filter(hasEmail);
505
+ * // => [{ name: 'John', email: 'john@example.com' }]
506
+ * // TypeScript knows these have email property
507
+ *
508
+ * @example
509
+ * // Feature detection
510
+ * const supportsWebGL = hasProperty('WebGLRenderingContext');
511
+ * if (supportsWebGL(window)) {
512
+ * // Initialize WebGL...
513
+ * }
514
+ *
515
+ * @example
516
+ * // Optional property handling
517
+ * interface User {
518
+ * id: string;
519
+ * name: string;
520
+ * avatar?: string;
521
+ * }
522
+ *
523
+ * const hasAvatar = hasProperty('avatar');
524
+ * const usersWithAvatars = users.filter(hasAvatar);
525
+ * // Now TypeScript knows avatar exists on these users
526
+ *
527
+ * @since 2025-07-03
528
+ */
529
+ export declare const hasProperty: <K extends PropertyKey>(key: K) => <T extends object>(obj: T) => obj is T & Record<K, unknown>;
530
+ /**
531
+ * Creates a predicate that checks if an array includes a specific value.
532
+ * @description Creates a predicate function that tests array membership.
533
+ * Uses Array.includes internally, so it uses SameValueZero equality.
534
+ *
535
+ * @template T - The type of elements in the array
536
+ * @param {T} target - The value to search for in arrays
537
+ * @returns {(array: T[]) => boolean} A predicate that returns true if the array includes the target
538
+ *
539
+ * @category Array
540
+ * @example
541
+ * // Language filtering
542
+ * const hasFavorite = includes('JavaScript');
543
+ * const jsDevs = developers.filter(dev => hasFavorite(dev.languages));
544
+ *
545
+ * @example
546
+ * // Tag filtering
547
+ * const hasUrgentTag = includes('urgent');
548
+ * const urgentTasks = tasks.filter(task => hasUrgentTag(task.tags));
549
+ *
550
+ * @example
551
+ * // Permission checking
552
+ * const hasAdminPermission = includes('admin');
553
+ * const adminActions = actions.filter(action =>
554
+ * hasAdminPermission(action.requiredPermissions)
555
+ * );
556
+ *
557
+ * @see oneOf - Check if value is one of multiple values
558
+ * @since 2025-07-03
559
+ */
560
+ export declare const includes: <T>(target: T) => (array: T[]) => boolean;
561
+ /**
562
+ * Creates a predicate that always returns true.
563
+ * @description Useful as a default predicate, for conditional filtering,
564
+ * or as a placeholder during development. The parameter is ignored.
565
+ *
566
+ * @template T - The type of the ignored parameter
567
+ * @param {T} _ - Value is ignored
568
+ * @returns {boolean} Always returns true
569
+ *
570
+ * @category Constants
571
+ * @example
572
+ * // Admin bypass for filters
573
+ * const filters = {
574
+ * status: user.role === 'admin' ? alwaysTrue : equals('published')
575
+ * };
576
+ *
577
+ * @example
578
+ * // Conditional filtering
579
+ * const nameFilter = searchTerm
580
+ * ? (user: User) => user.name.includes(searchTerm)
581
+ * : alwaysTrue;
582
+ *
583
+ * @example
584
+ * // Feature toggle
585
+ * const canAccessFeature = FEATURE_ENABLED ? hasPermission('feature') : alwaysTrue;
586
+ *
587
+ * @see alwaysFalse - Predicate that always returns false
588
+ * @since 2025-07-03
589
+ */
590
+ export declare const alwaysTrue: <T>(_: T) => boolean;
591
+ /**
592
+ * Creates a predicate that always returns false.
593
+ * @description Useful for disabling features, creating empty filter results,
594
+ * or as a placeholder during development. The parameter is ignored.
595
+ *
596
+ * @template T - The type of the ignored parameter
597
+ * @param {T} _ - Value is ignored
598
+ * @returns {boolean} Always returns false
599
+ *
600
+ * @category Constants
601
+ * @example
602
+ * // Conditional record display
603
+ * const filters = {
604
+ * deleted: showDeleted ? alwaysTrue : alwaysFalse
605
+ * };
606
+ *
607
+ * @example
608
+ * // Feature flags
609
+ * const canAccessBeta = BETA_ENABLED ? hasRole('beta') : alwaysFalse;
610
+ *
611
+ * @example
612
+ * // Maintenance mode
613
+ * const canPerformAction = MAINTENANCE_MODE ? alwaysFalse : hasPermission('action');
614
+ *
615
+ * @see alwaysTrue - Predicate that always returns true
616
+ * @since 2025-07-03
617
+ */
618
+ export declare const alwaysFalse: <T>(_: T) => boolean;
619
+ /**
620
+ * Higher-order predicate utilities for complex compositions.
621
+ * @description Advanced utilities for creating and transforming predicates.
622
+ * These functions provide powerful patterns for building complex predicates
623
+ * from simpler ones.
624
+ *
625
+ * @category Advanced
626
+ * @since 2025-07-03
627
+ */
628
+ export declare const predicateUtils: {
629
+ /**
630
+ * Creates a predicate based on a property value.
631
+ * @description Checks if an object's property equals a specific value.
632
+ * Uses strict equality (===) for comparison.
633
+ *
634
+ * @template T - The type of the object
635
+ * @template K - The type of the property key
636
+ * @param {K} key - The property key to check
637
+ * @param {T[K]} value - The value to compare against
638
+ * @returns {(obj: T) => boolean} A predicate that checks the property value
639
+ *
640
+ * @example
641
+ * // Role-based filtering
642
+ * const isAdminRole = predicateUtils.propEquals('role', 'admin');
643
+ * const admins = users.filter(isAdminRole);
644
+ *
645
+ * @example
646
+ * // Status checking
647
+ * const isPublished = predicateUtils.propEquals('status', 'published');
648
+ * const publishedPosts = posts.filter(isPublished);
649
+ *
650
+ * @since 2025-07-03
651
+ */
652
+ propEquals: <T, K extends keyof T>(key: K, value: T[K]) => (obj: T) => boolean;
653
+ /**
654
+ * Creates a predicate that checks multiple properties.
655
+ * @description Checks if an object matches all properties in a partial object.
656
+ * Only checks properties that exist in the partial object.
657
+ *
658
+ * @template T - The type of the object being checked
659
+ * @param {Partial<T>} partial - Object with properties to match
660
+ * @returns {(obj: T) => boolean} A predicate that checks all properties match
661
+ *
662
+ * @example
663
+ * // Finding specific users
664
+ * const isJohnDoe = predicateUtils.propsMatch({
665
+ * firstName: 'John',
666
+ * lastName: 'Doe'
667
+ * });
668
+ *
669
+ * const johnDoe = users.find(isJohnDoe);
670
+ *
671
+ * @example
672
+ * // Filtering by multiple criteria
673
+ * const isTargetProduct = predicateUtils.propsMatch({
674
+ * category: 'electronics',
675
+ * inStock: true,
676
+ * featured: true
677
+ * });
678
+ *
679
+ * const featuredElectronics = products.filter(isTargetProduct);
680
+ *
681
+ * @since 2025-07-03
682
+ */
683
+ propsMatch: <T extends object>(partial: Partial<T>) => (obj: T) => boolean;
684
+ /**
685
+ * Creates a predicate that applies a transformation before testing.
686
+ * @description Contramap allows you to adapt a predicate for one type to work
687
+ * with another type by providing a transformation function. This is the
688
+ * contravariant functor operation for predicates.
689
+ *
690
+ * @template A - The input type
691
+ * @template B - The type the predicate expects
692
+ * @param {(a: A) => B} transform - Function to transform A to B
693
+ * @param {(b: B) => boolean} predicate - Predicate that operates on type B
694
+ * @returns {(value: A) => boolean} A predicate that operates on type A
695
+ *
696
+ * @example
697
+ * // Extract property before testing
698
+ * const hasLongName = predicateUtils.contramap(
699
+ * (user: { name: string }) => user.name,
700
+ * (name: string) => name.length > 10
701
+ * );
702
+ *
703
+ * @example
704
+ * // Case-insensitive comparison
705
+ * const isCaseInsensitiveMatch = (target: string) =>
706
+ * predicateUtils.contramap(
707
+ * (s: string) => s.toLowerCase(),
708
+ * equals(target.toLowerCase())
709
+ * );
710
+ *
711
+ * @example
712
+ * // Date comparison
713
+ * const isAfter2020 = predicateUtils.contramap(
714
+ * (date: Date) => date.getFullYear(),
715
+ * (year: number) => year > 2020
716
+ * );
717
+ *
718
+ * @since 2025-07-03
719
+ */
720
+ contramap: <A, B>(transform: (a: A) => B, predicate: (b: B) => boolean) => (value: A) => boolean;
721
+ };
722
+ //# sourceMappingURL=predicates.d.mts.map