import type {
TPredicate,
TPredicateAsserting,
Plucked,
ExtractPlucked,
EmptyValue,
FalsyValue
} from './common';
// Helper: if a pluck appears anywhere in P, use that type; otherwise fallback to PatternAsType
type HandlerValue
=
ExtractPlucked
extends never
? PatternAsType
: ExtractPlucked
;
// Helper type to convert a union of types to an intersection.
type UnionToIntersection = (
U extends unknown ? (k: U) => void : never
) extends (k: infer I) => void
? I
: never;
/**
* Recursively infers a TypeScript type from a match-iz pattern.
* @template P - The type of the pattern.
*/
export type PatternAsType
= P extends RegExp
? RegExpMatchArray | Record // Handle RegExp patterns
: P extends (value: unknown) => value is infer R
? R // Handle type guard predicates, extracting the guarded type.
: P extends (value: infer V) => boolean
? V // Handle simple boolean predicates, inferring the input type.
: P extends readonly (infer E)[]
? readonly PatternAsType[] // Handle array patterns recursively.
: P extends object
? { -readonly [K in keyof P]: PatternAsType
} // Handle object patterns recursively.
: P; // Handle literal values (string, number, etc.).
// Infer a union of types from a tuple of patterns.
type UnionPatternTypes
= PatternAsType
;
// Infer an intersection of types from a tuple of patterns.
type IntersectPatternTypes
= UnionToIntersection<
UnionPatternTypes
>;
export type TPattern = Input | TPredicate;
/**
* The type of the value captured by the `rest()` pattern matcher.
* It can be an array of values, an object with string keys and values, or undefined.
*/
export type TRestResult = unknown[] | Record | undefined;
export type THandler = (
value: Input,
rest: TRestResult
) => Output;
export type TEvaluator = {
matched: (value: Input) => boolean;
value: (value: Input) => Output;
};
export type TMatchTester = (
value: Input
) => TEvaluator | Output;
// Infer the union of return types from a list of handlers.
type InferHandlerOutput = T extends TMatchTester ? O : never;
export type TIterationLimit = number;
export type TPreviousIterationLimit = number;
declare module 'match-iz' {
/**
* Returns the current iteration limit for recursive patterns.
*
* The default limit is 20,000.
*
* @returns {TIterationLimit} The current iteration limit.
*/
export function getIterationLimit(): TIterationLimit;
/**
* Sets a new iteration limit for recursive patterns.
*
* The default limit is 20,000.
*
* @param {TIterationLimit} newMaxiumum - The new iteration limit.
* @returns {() => TPreviousIterationLimit} A function that restores the previous limit.
*/
export function setIterationLimit(
newMaxiumum: TIterationLimit
): () => TPreviousIterationLimit;
/**
* Creates a reusable pattern matching function.
*
* @template Input - The type of the value to match against.
* @template {readonly TMatchTester[]} T - A tuple of `when` and `otherwise` clauses.
* @param {...T} needles - A sequence of `when` and `otherwise` clauses.
* @returns {(haystack: Input) => InferHandlerOutput} A function that takes a value and executes the pattern match.
* @example
* import { against, when, otherwise } from 'match-iz';
*
* const isSuccess = against(
* when({ statusCode: 200 }, ({ body }) => body),
* otherwise(() => null)
* );
*
* const result = isSuccess({
* statusCode: 200,
* body: 'Success!'
* }); // 'Success!'
*
* @example
* import { against, when, isNumber, gt, otherwise } from 'match-iz';
*
* const categorizeNumber = against(
* when(isNumber, (num) => {
* if (num > 0) return 'Positive';
* if (num < 0) return 'Negative';
* return 'Zero';
* }),
* otherwise(() => 'Not a number')
* );
*
* categorizeNumber(5); // 'Positive'
* categorizeNumber(-3); // 'Negative'
* categorizeNumber(0); // 'Zero'
* categorizeNumber('abc'); // 'Not a number'
*/
export function against<
Input,
const T extends readonly TMatchTester[]
>(
...needles: T
): (haystack: Input) => InferHandlerOutput;
/**
* Matches a value against a series of patterns.
*
* @template Input - The type of the value to match against.
* @param {Input} haystack - The value to match.
* @returns {[]>(...needles: T) => InferHandlerOutput} A function that takes a sequence of `when` and `otherwise` clauses.
* @example
* import { match, when, otherwise } from 'match-iz';
*
* const response = { statusCode: 200, body: 'Success!' };
*
* const result = match(response)(
* when({ statusCode: 200 }, ({ body }) => body),
* when({ statusCode: 404 }, () => 'Not Found'),
* otherwise(() => 'Error')
* ); // 'Success!'
*
* @example
* import { match, when, isString, isNumber, otherwise } from 'match-iz';
*
* const processInput = (input) => match(input)(
* when(isString, (str) => `String: ${str.toUpperCase()}`),
* when(isNumber, (num) => `Number: ${num * 2}`),
* otherwise(() => 'Unknown type')
* );
*
* processInput('hello'); // 'String: HELLO'
* processInput(10); // 'Number: 20'
* processInput(true); // 'Unknown type'
*/
export function match(
haystack: Input
): <
const T extends readonly TMatchTester[]
>(
...needles: T
) => InferHandlerOutput;
/**
* Defines a pattern and a corresponding handler.
*
* @template P - The pattern to match against.
* @template O - The output type of the handler.
* @param {P} pattern - The pattern to match. Can be a literal value, an object, an array, or a predicate function.
* @param {THandler, O> | O} handler - The handler to execute if the pattern matches. Can be a function or a value.
* @returns {TMatchTester} A match tester object.
* @example
* import { match, when, otherwise } from 'match-iz';
*
* const result = match(10)(
* when(10, 'Ten'),
* otherwise('Not Ten')
* ); // 'Ten'
*
* @example
* import { match, when, isString, otherwise } from 'match-iz';
*
* const greet = (name) => match(name)(
* // Handler can be a function
* when(isString, (n) => `Hello, ${n}!`),
* otherwise('Hello, stranger!')
* );
* greet('Alice'); // 'Hello, Alice!'
*/
export function when
(
pattern: P,
handler: THandler, O> | O
): TMatchTester;
/**
* Defines a pattern and returns a function that takes a handler.
*
* @template P - The pattern to match against.
* @param {P} pattern - The pattern to match.
* @returns {(handler: THandler, O> | O) => TMatchTester} A function that takes a handler and returns a match tester object.
* @example
* import { match, when, isNumber, otherwise } from 'match-iz';
*
* const checkValue = match(5)(
* // Curried usage
* when(isNumber)((num) => `The number is ${num}`),
* otherwise(() => 'Not a number')
* );
*
* checkValue; // 'The number is 5'
*/
export function when
(
pattern: P
): (
handler: THandler, O> | O
) => TMatchTester;
/**
* Defines a pattern with a guard and a corresponding handler.
*
* @template P - The pattern to match against.
* @template G1 - The first guard pattern.
* @template O - The output type of the handler.
* @param {P} pattern - The main pattern.
* @param {G1} guard1 - The first guard pattern.
* @param {THandler & PatternAsType, O> | O} handler - The handler to execute if all patterns match.
* @returns {TMatchTester} A match tester object.
* @example
* import { match, when, isNumber, gt, otherwise } from 'match-iz';
*
* const checkAge = (age) => match(age)(
* when(isNumber, gt(18), (a) => `Adult: ${a}`),
* otherwise(() => 'Minor')
* );
*
* checkAge(25); // 'Adult: 25'
* checkAge(16); // 'Minor'
*/
export function when
(
pattern: P,
guard1: G1,
handler: THandler & PatternAsType, O> | O
): TMatchTester;
/**
* Defines a pattern with two guards and a corresponding handler.
*
* @template P - The pattern to match against.
* @template G1 - The first guard pattern.
* @template G2 - The second guard pattern.
* @template O - The output type of the handler.
* @param {P} pattern - The main pattern.
* @param {G1} guard1 - The first guard pattern.
* @param {G2} guard2 - The second guard pattern.
* @param {THandler & PatternAsType & PatternAsType, O> | O} handler - The handler to execute if all patterns match.
* @returns {TMatchTester} A match tester object.
* @example
* import { match, when, isString, startsWith, endsWith, otherwise } from 'match-iz';
*
* const checkWord = (word) => match(word)(
* when(isString, startsWith('pre'), endsWith('fix'), (w) => `Prefix-Suffix: ${w}`),
* otherwise(() => 'No match')
* );
*
* checkWord('prefix'); // 'Prefix-Suffix: prefix'
* checkWord('suffix'); // 'No match'
*/
export function when
&
PatternAsType &
PatternAsType,
O
> | O
): TMatchTester;
/**
* Defines a pattern with three guards and a corresponding handler.
*
* @template P - The pattern to match against.
* @template G1 - The first guard pattern.
* @template G2 - The second guard pattern.
* @template G3 - The third guard pattern.
* @template O - The output type of the handler.
* @param {P} pattern - The main pattern.
* @param {G1} guard1 - The first guard pattern.
* @param {G2} guard2 - The second guard pattern.
* @param {G3} guard3 - The third guard pattern.
* @param {THandler & PatternAsType & PatternAsType & PatternAsType, O> | O} handler - The handler to execute if all patterns match.
* @returns {TMatchTester} A match tester object.
*/
export function when
&
PatternAsType &
PatternAsType &
PatternAsType,
O
> | O
): TMatchTester;
/**
* Defines a pattern with four guards and a corresponding handler.
*
* @template P - The pattern to match against.
* @template G1 - The first guard pattern.
* @template G2 - The second guard pattern.
* @template G3 - The third guard pattern.
* @template G4 - The fourth guard pattern.
* @template O - The output type of the handler.
* @param {P} pattern - The main pattern.
* @param {G1} guard1 - The first guard pattern.
* @param {G2} guard2 - The second guard pattern.
* @param {G3} guard3 - The third guard pattern.
* @param {G4} guard4 - The fourth guard pattern.
* @param {THandler & PatternAsType & PatternAsType & PatternAsType & PatternAsType, O> | O} handler - The handler to execute if all patterns match.
* @returns {TMatchTester} A match tester object.
*/
export function when
&
PatternAsType &
PatternAsType &
PatternAsType &
PatternAsType,
O
> | O
): TMatchTester;
/**
* Defines a pattern with five guards and a corresponding handler.
*
* @template P - The pattern to match against.
* @template G1 - The first guard pattern.
* @template G2 - The second guard pattern.
* @template G3 - The third guard pattern.
* @template G4 - The fourth guard pattern.
* @template G5 - The fifth guard pattern.
* @template O - The output type of the handler.
* @param {P} pattern - The main pattern.
* @param {G1} guard1 - The first guard pattern.
* @param {G2} guard2 - The second guard pattern.
* @param {G3} guard3 - The third guard pattern.
* @param {G4} guard4 - The fourth guard pattern.
* @param {G5} guard5 - The fifth guard pattern.
* @param {THandler & PatternAsType & PatternAsType & PatternAsType & PatternAsType & PatternAsType, O> | O} handler - The handler to execute if all patterns match.
* @returns {TMatchTester} A match tester object.
*/
export function when
&
PatternAsType &
PatternAsType &
PatternAsType &
PatternAsType &
PatternAsType,
O
> | O
): TMatchTester;
/**
* Defines a default handler when no other patterns match.
*
* @template Input - The type of the value passed to the handler.
* @template Output - The output type of the handler.
* @param {THandler | Output} handler - The handler to execute. Can be a function or a value.
* @returns {TMatchTester} A match tester object.
* @example
* import { match, when, otherwise } from 'match-iz';
*
* const getValue = (input) => match(input)(
* when(1, 'One'),
* when(2, 'Two'),
* otherwise('Other') // Default case
* );
*
* getValue(3); // 'Other'
*/
export function otherwise(
handler: THandler | Output
): TMatchTester;
/**
* A catamorphism for matching, allowing for recursive data structures.
*
* @param {unknown} catas - The catamorphism definition.
* @returns {unknown} The result of the catamorphism.
* @example
* // This is a more advanced feature and typically used for recursive data structures.
* // For a full example, refer to the match-iz documentation or tests.
* import { cata, when, otherwise } from 'match-iz';
*
* const List = cata({
* getValue: (list) => list.value,
* Empty: (list) => !list.value && !list.next,
* Node: (list) => list.value && list.next,
* });
*
* const sumList = (list) => match(list)(
* List.Empty(() => 0),
* List.Node((value, next) => value + sumList(next)),
* otherwise(() => {
* throw new Error('Invalid list structure');
* })
* );
*
* const mylist = { value: 1, next: { value: 2, next: { value: 3, next: {} } } };
* sumList(mylist); // 6
*/
export function cata(catas: unknown): unknown;
/**
* A predicate that checks if a value is not `null` or `undefined`.
* @example
* import { match, when, defined, otherwise } from 'match-iz';
*
* const checkDefined = (value) => match(value)(
* when(defined, () => 'Value is defined'),
* otherwise(() => 'Value is undefined or null')
* );
*
* checkDefined(10); // 'Value is defined'
* checkDefined(null); // 'Value is undefined or null'
* checkDefined(undefined); // 'Value is undefined or null'
*/
export const defined: TPredicateAsserting>;
/**
* A predicate that checks if a value is empty (e.g., empty string, empty array, or empty object).
* @example
* import { match, when, empty, otherwise } from 'match-iz';
*
* const checkEmpty = (value) => match(value)(
* when(empty, () => 'Value is empty'),
* otherwise(() => 'Value is not empty')
* );
*
* checkEmpty(''); // 'Value is empty'
* checkEmpty([]); // 'Value is empty'
* checkEmpty({}); // 'Value is empty'
* checkEmpty('hello'); // 'Value is not empty'
*/
export const empty: TPredicateAsserting;
/**
* A predicate that checks if a value is truthy.
* @example
* import { match, when, truthy, otherwise } from 'match-iz';
*
* const checkTruthy = (value) => match(value)(
* when(truthy, () => 'Value is truthy'),
* otherwise(() => 'Value is falsy')
* );
*
* checkTruthy(true); // 'Value is truthy'
* checkTruthy(1); // 'Value is truthy'
* checkTruthy('abc'); // 'Value is truthy'
* checkTruthy(false); // 'Value is falsy'
* checkTruthy(0); // 'Value is falsy'
* checkTruthy(''); // 'Value is falsy'
*/
export const truthy: TPredicateAsserting>;
/**
* A predicate that checks if a value is falsy.
* @example
* import { match, when, falsy, otherwise } from 'match-iz';
*
* const checkFalsy = (value) => match(value)(
* when(falsy, () => 'Value is falsy'),
* otherwise(() => 'Value is truthy')
* );
*
* checkFalsy(false); // 'Value is falsy'
* checkFalsy(null); // 'Value is falsy'
* checkFalsy(1); // 'Value is truthy'
*/
export const falsy: TPredicateAsserting;
/**
* A predicate that checks if a number is greater than the specified value.
*
* @param {number} greaterThan - The value to compare against.
* @returns {TPredicateAsserting} A predicate function.
* @example
* import { match, when, gt, otherwise } from 'match-iz';
*
* const checkScore = (score) => match(score)(
* when(gt(90), () => 'Excellent!'),
* otherwise(() => 'Good.')
* );
*
* checkScore(95); // 'Excellent!'
* checkScore(80); // 'Good.'
*/
export function gt(greaterThan: number): TPredicateAsserting;
/**
* A predicate that checks if a number is less than the specified value.
*
* @param {number} lessThan - The value to compare against.
* @returns {TPredicateAsserting} A predicate function.
* @example
* import { match, when, lt, otherwise } from 'match-iz';
*
* const checkTemperature = (temp) => match(temp)(
* when(lt(0), () => 'Freezing!'),
* otherwise(() => 'Above freezing.')
* );
*
* checkTemperature(-5); // 'Freezing!'
* checkTemperature(5); // 'Above freezing.'
*/
export function lt(lessThan: number): TPredicateAsserting;
/**
* A predicate that checks if a number is greater than or equal to the specified value.
*
* @param {number} greaterThanOrEqualTo - The value to compare against.
* @returns {TPredicateAsserting} A predicate function.
* @example
* import { match, when, gte, otherwise } from 'match-iz';
*
* const checkMinAge = (age) => match(age)(
* when(gte(18), () => 'Eligible'),
* otherwise(() => 'Not eligible')
* );
*
* checkMinAge(18); // 'Eligible'
* checkMinAge(17); // 'Not eligible'
*/
export function gte(greaterThanOrEqualTo: number): TPredicateAsserting;
/**
* A predicate that checks if a number is less than or equal to the specified value.
*
* @param {number} lessThanOrEqualTo - The value to compare against.
* @returns {TPredicateAsserting} A predicate function.
* @example
* import { match, when, lte, otherwise } from 'match-iz';
*
* const checkMaxItems = (count) => match(count)(
* when(lte(5), () => 'Within limit'),
* otherwise(() => 'Exceeds limit')
* );
*
* checkMaxItems(5); // 'Within limit'
* checkMaxItems(6); // 'Exceeds limit'
*/
export function lte(lessThanOrEqualTo: number): TPredicateAsserting;
/**
* A predicate that checks if a number is within a specified range (inclusive).
*
* @param {number} min - The minimum value of the range.
* @param {number} max - The maximum value of the range.
* @returns {TPredicateAsserting} A predicate function.
* @example
* import { match, when, inRange, otherwise } from 'match-iz';
*
* const checkGrade = (grade) => match(grade)(
* when(inRange(90, 100), () => 'A'),
* when(inRange(80, 89), () => 'B'),
* otherwise(() => 'C or lower')
* );
*
* checkGrade(92); // 'A'
* checkGrade(85); // 'B'
* checkGrade(70); // 'C or lower'
*/
export function inRange(min: number, max: number): TPredicateAsserting;
/**
* A predicate that checks if a string starts with the specified text.
*
* @param {string} text - The text to check for.
* @returns {TPredicateAsserting} A predicate function.
* @example
* import { match, when, startsWith, otherwise } from 'match-iz';
*
* const checkPrefix = (str) => match(str)(
* when(startsWith('http'), () => 'Web URL'),
* otherwise(() => 'Other string')
* );
*
* checkPrefix('https://example.com'); // 'Web URL'
* checkPrefix('ftp://example.com'); // 'Other string'
*/
export function startsWith(text: string): TPredicateAsserting;
/**
* A predicate that checks if a string ends with the specified text.
*
* @param {string} text - The text to check for.
* @returns {TPredicateAsserting} A predicate function.
* @example
* import { match, when, endsWith, otherwise } from 'match-iz';
*
* const checkSuffix = (str) => match(str)(
* when(endsWith('.jpg'), () => 'JPEG image'),
* otherwise(() => 'Other file type')
* );
*
* checkSuffix('photo.jpg'); // 'JPEG image'
* checkSuffix('document.pdf'); // 'Other file type'
*/
export function endsWith(text: string): TPredicateAsserting;
/**
* A predicate that checks if a string or array includes the specified content.
*
* @param {unknown} content - The content to check for.
* @returns {TPredicate} A predicate function.
* @example
* import { match, when, includes, otherwise } from 'match-iz';
*
* const checkContent = (data) => match(data)(
* when(includes('apple'), () => 'Contains apple'),
* otherwise(() => 'Does not contain apple')
* );
*
* checkContent('red apple'); // 'Contains apple'
* checkContent(['banana', 'apple']); // 'Contains apple'
* checkContent('orange'); // 'Does not contain apple'
*/
export function includes(
content: string
): TPredicateAsserting;
/**
* A predicate that checks if a string or array includes the specified content.
*
* @param {unknown} content - The content to check for.
* @returns {TPredicate} A predicate function.
* @example
* import { match, when, includes, otherwise } from 'match-iz';
*
* const checkContent = (data) => match(data)(
* when(includes('apple'), () => 'Contains apple'),
* otherwise(() => 'Does not contain apple')
* );
*
* checkContent('red apple'); // 'Contains apple'
* checkContent(['banana', 'apple']); // 'Contains apple'
* checkContent('orange'); // 'Does not contain apple'
*/
export function includes(
content: Array
): TPredicateAsserting;
/**
* A predicate that checks if a value is equal to the pattern. It differs
* from the default pattern matching by requiring the value to have the
* same number of properties (for objects) or elements (for arrays) as
* the pattern.
*
* @template P - The pattern to match against.
* @param {P} pattern - The pattern to check for equality against.
* @returns {TPredicateAsserting>} A predicate function.
* @example
* import { match, when, eq, otherwise } from 'match-iz';
*
* const matchValue = (value) => match(value)(
* when(eq({ a: 1 }), () => 'Matches { a: 1 }'),
* otherwise(() => 'No match')
* );
*
* matchValue({ a: 1 }); // 'Matches { a: 1 }'
* matchValue({ a: 1, b: 2 }); // 'No match'
*/
export function eq
(pattern: P): TPredicateAsserting>;
/**
* A predicate that checks for deep value equality, recursively applying
* `eq` to nested objects.
*
* @template P - The pattern to match against.
* @param {P} pattern - The pattern to check for deep equality against.
* @returns {TPredicateAsserting>} A predicate function.
* @example
* import { match, when, deepEq, otherwise } from 'match-iz';
*
* const matchValue = (value) => match(value)(
* when(deepEq({ a: { b: 2 } }), () => 'Matches { a: { b: 2 } }'),
* otherwise(() => 'No match')
* );
*
* matchValue({ a: { b: 2 } }); // 'Matches { a: { b: 2 } }'
* matchValue({ a: { b: 2, c: 3 } }); // 'No match'
*/
export function deepEq
(pattern: P): TPredicateAsserting>;
/**
* A predicate that negates the result of another pattern.
*
* @param {TPattern} pattern - The pattern to negate.
* @returns {TPredicate} A predicate function.
* @example
* import { match, when, not, isString, otherwise } from 'match-iz';
*
* const checkNotString = (value) => match(value)(
* when(not(isString), () => 'Not a string'),
* otherwise(() => 'Is a string')
* );
*
* checkNotString(123); // 'Not a string'
* checkNotString('test'); // 'Is a string'
*/
export function not
(
pattern: P
): P extends (v: unknown) => v is infer K
? (v: unknown) => v is Exclude
: (v: unknown) => boolean;
/**
* A combinator that checks if a value matches all of the specified patterns.
*
* @template {readonly TPattern[]} P - A tuple of patterns.
* @param {...P} these - The patterns to check against.
* @returns {TPredicateAsserting>} A predicate
* function.
* @example
* import { match, when, allOf, isNumber, gt, lt, otherwise } from 'match-iz';
*
* const checkRange = (num) => match(num)(
* when(allOf(isNumber, gt(5), lt(10)), () => 'Number between 5 and 10'),
* otherwise(() => 'Out of range')
* );
*
* checkRange(7); // 'Number between 5 and 10'
* checkRange(3); // 'Out of range'
* checkRange(12); // 'Out of range'
*/
export function allOf(
...these: P
): TPredicateAsserting>;
/**
* A combinator that checks if a value matches any of the specified patterns.
*
* @template {readonly TPattern[]} P - A tuple of patterns.
* @param {...P} these - The patterns to check against.
* @returns {TPredicateAsserting>} A predicate function.
* @example
* import { match, when, anyOf, isString, isNumber, otherwise } from 'match-iz';
*
* const checkType = (value) => match(value)(
* when(anyOf(isString, isNumber), () => 'String or Number'),
* otherwise(() => 'Other type')
* );
*
* checkType('hello'); // 'String or Number'
* checkType(123); // 'String or Number'
* checkType(true); // 'Other type'
*/
export function anyOf(
...these: P
): TPredicateAsserting>;
/**
* A combinator that checks if a value matches any of the specified patterns, returning the first match.
*
* @template {readonly TPattern[]} P - A tuple of patterns.
* @param {...P} these - The patterns to check against.
* @returns {TPredicateAsserting>} A predicate function.
* @example
* import { match, when, firstOf, otherwise } from 'match-iz';
*
* const processArray = (arr) => match(arr)(
* when(firstOf(1, 2), () => 'Starts with 1 or 2'),
* otherwise(() => 'Does not start with 1 or 2')
* );
*
* processArray([1, 2, 3]); // 'Starts with 1 or 2'
* processArray([2, 3, 4]); // 'Starts with 1 or 2'
* processArray([3, 4, 5]); // 'Does not start with 1 or 2'
*/
export function firstOf(
...these: P
): TPredicateAsserting>;
/**
* A combinator that checks if a value matches any of the specified patterns, returning the last match.
*
* @template {readonly TPattern[]} P - A tuple of patterns.
* @param {...P} these - The patterns to check against.
* @returns {TPredicateAsserting>} A predicate function.
* @example
* import { match, when, lastOf, otherwise } from 'match-iz';
*
* const processArray = (arr) => match(arr)(
* when(lastOf(3, 4), () => 'Ends with 3 or 4'),
* otherwise(() => 'Does not end with 3 or 4')
* );
*
* processArray([1, 2, 3]); // 'Ends with 3 or 4'
* processArray([2, 3, 4]); // 'Ends with 3 or 4'
* processArray([4, 5, 6]); // 'Does not end with 3 or 4'
*/
export function lastOf(
...these: P
): TPredicateAsserting>;
/**
* A predicate that checks if at least one element in an array matches the specified pattern.
*
* @template P - The pattern to match against.
* @param {P} pattern - The pattern to check.
* @returns {TPredicateAsserting>>} A predicate function.
* @example
* import { match, when, some, gt, otherwise } from 'match-iz';
*
* const checkPositive = (arr) => match(arr)(
* when(some(gt(0)), () => 'Contains at least one positive number'),
* otherwise(() => 'No positive numbers')
* );
*
* checkPositive([-1, 0, 5]); // 'Contains at least one positive number'
* checkPositive([-2, -1, 0]); // 'No positive numbers'
*/
export function some
(pattern: P): TPredicateAsserting>>;
/**
* A predicate that checks if every element in an array matches the specified pattern.
*
* @template P - The pattern to match against.
* @param {P} pattern - The pattern to check.
* @returns {TPredicateAsserting>>} A predicate function.
* @example
* import { match, when, every, isNumber, otherwise } from 'match-iz';
*
* const checkAllNumbers = (arr) => match(arr)(
* when(every(isNumber), () => 'All elements are numbers'),
* otherwise(() => 'Not all elements are numbers')
* );
*
* checkAllNumbers([1, 2, 3]); // 'All elements are numbers'
* checkAllNumbers([1, 'a', 3]); // 'Not all elements are numbers'
*/
export function every
(pattern: P): TPredicateAsserting>>;
/**
* A predicate that checks if a value is included in the specified list of values.
*
* @template {readonly unknown[]} P - A tuple of values.
* @param {...P} these - The values to check against.
* @returns {TPredicateAsserting
} A predicate function.
* @example
* import { match, when, includedIn, otherwise } from 'match-iz';
*
* const checkColor = (color) => match(color)(
* when(includedIn('red', 'green', 'blue'), () => 'Primary color'),
* otherwise(() => 'Other color')
* );
*
* checkColor('red'); // 'Primary color'
* checkColor('yellow'); // 'Other color'
*/
export function includedIn(
...these: P
): TPredicateAsserting>;
/**
* A predicate that checks if an object has the specified own properties.
*
* @param {...string[]} props - The properties to check for.
* @returns {TPredicateAsserting>} A predicate function.
* @example
* import { match, when, hasOwn, otherwise } from 'match-iz';
*
* const checkUser = (user) => match(user)(
* when(hasOwn('name', 'email'), () => 'Valid user object'),
* otherwise(() => 'Invalid user object')
* );
*
* checkUser({ name: 'Alice', email: 'a@example.com' }); // 'Valid user object'
* checkUser({ name: 'Bob' }); // 'Invalid user object'
*/
export function hasOwn(...props: string[]): TPredicateAsserting>;
/**
* A predicate that checks if an object is an instance of the specified constructor.
*
* @template T - The type of the instance.
* @param {new (...args: unknown[]) => T} constructor - The constructor to check against.
* @returns {TPredicateAsserting} A predicate function.
* @example
* import { match, when, instanceOf, otherwise } from 'match-iz';
*
* class MyClass {}
*
* const checkInstance = (obj) => match(obj)(
* when(instanceOf(MyClass), () => 'Is MyClass instance'),
* otherwise(() => 'Not MyClass instance')
* );
*
* checkInstance(new MyClass()); // 'Is MyClass instance'
* checkInstance({}); // 'Not MyClass instance'
*/
export function instanceOf(constructor: new (...args: unknown[]) => T): TPredicateAsserting;
/**
* “Pluck” any sub‑pattern out of the match target and hand its value
* to your handler. If you supply a pattern `P`, it will only match
* when that sub‑pattern matches, and the handler will get the inner
* `PatternAsType
`.
*
* @param {P} [pattern] — any match‑iz pattern (literal, object, array, predicate, etc.)
* @returns `Plucked>` at type‑level; at runtime it’s your
* predicate/function/regexp/etc. unchanged.
*
* @example
* when({ foo: pluck(isString) }, (s) => s); // string
* when({ foo: pluck(/bar/) }, (m) => m); // RegExpMatchArray
* when({ foo: pluck({ a:1 }) }, (o) => o); // { a: number }
*/
export function pluck
(
pattern?: P
): Plucked>;
/**
* Captures the remaining elements of an array or properties of an object.
*
* @param {TPattern} [pattern] - An optional pattern that the remaining items must match.
* @returns {object} A special object to be used inside array or object patterns.
* @remarks When used in an array pattern, `rest()` should typically be the last element to capture the remaining elements. When used in an object pattern, it should be spread (`...rest()`) to capture remaining properties. The captured values are passed as the second argument to the handler, and their type will be `TRestResult`. You can use a type assertion in the handler if you have more specific knowledge about the shape of the rest value.
* @example
* // Array rest
* import { match, when, rest, otherwise } from 'match-iz';
*
* const processArray = (arr) => match(arr)(
* when([1, 2, rest()], (value, rest) => `Rest: ${(rest as number[]).join(',')}`),
* otherwise(() => 'No match')
* );
*
* processArray([1, 2, 3, 4]); // 'Rest: 3,4'
*
* @example
* // Object rest
* import { match, when, rest, otherwise } from 'match-iz';
*
* const processObject = (obj) => match(obj)(
* when({ a: 1, ...rest() }, (value, rest) => `Rest: ${JSON.stringify(rest)}`),
* otherwise(() => 'No match')
* );
*
* processObject({ a: 1, b: 2, c: 3 }); // 'Rest: {"b":2,"c":3}'
*/
export function rest(pattern?: TPattern): object;
/**
* A predicate that checks if a value is an array.
* @example
* import { match, when, isArray, otherwise } from 'match-iz';
*
* const checkType = (value) => match(value)(
* when(isArray, () => 'Is an array'),
* otherwise(() => 'Not an array')
* );
*
* checkType([1, 2, 3]); // 'Is an array'
* checkType('abc'); // 'Not an array'
*/
export const isArray: TPredicateAsserting;
/**
* A predicate that checks if a value is a Date object.
* @example
* import { match, when, isDate, otherwise } from 'match-iz';
*
* const checkType = (value) => match(value)(
* when(isDate, () => 'Is a Date object'),
* otherwise(() => 'Not a Date object')
* );
*
* checkType(new Date()); // 'Is a Date object'
* checkType('2025-01-01'); // 'Not a Date object'
*/
export const isDate: TPredicateAsserting;
/**
* A predicate that checks if a value is a function.
* @example
* import { match, when, isFunction, otherwise } from 'match-iz';
*
* const checkType = (value) => match(value)(
* when(isFunction, () => 'Is a function'),
* otherwise(() => 'Not a function')
* );
*
* checkType(() => {}); // 'Is a function'
* checkType(123); // 'Not a function'
*/
export const isFunction: TPredicateAsserting<(...args: unknown[]) => unknown>;
/**
* A predicate that checks if a value is a number.
* @example
* import { match, when, isNumber, otherwise } from 'match-iz';
*
* const checkType = (value) => match(value)(
* when(isNumber, () => 'Is a number'),
* otherwise(() => 'Not a number')
* );
*
* checkType(123); // 'Is a number'
* checkType('123'); // 'Not a number'
*/
export const isNumber: TPredicateAsserting;
/**
* A predicate that checks if a value is a plain old JavaScript object.
* @example
* import { match, when, isPojo, otherwise } from 'match-iz';
*
* const checkType = (value) => match(value)(
* when(isPojo, () => 'Is a POJO'),
* otherwise(() => 'Not a POJO')
* );
*
* checkType({}); // 'Is a POJO'
* checkType(new Date()); // 'Not a POJO'
* checkType([]); // 'Not a POJO'
*/
export const isPojo: TPredicateAsserting