<D extends string>(field: D): <
R,
P extends Types.Tags<D, R> & string,
Ret,
Fn extends (_: Extract<R, Record<D, P>>) => Ret
>(
...pattern: [first: P, ...values: Array<P>, f: Fn]
) => <I, F, A, Pr>(
self: Matcher<I, F, R, A, Pr, Ret>
) => Matcher<
I,
Types.AddWithout<F, Extract<R, Record<D, P>>>,
Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>,
A | ReturnType<Fn>,
Pr,
Ret
>Matches values based on a specified discriminant field.
When to use
Use to match one or more exact values of a discriminator field.
Details
This function is used to define pattern matching on objects that follow a
discriminated union structure, where a specific field (e.g., type,
kind, _tag) determines the variant of the object. It allows matching
multiple values of the discriminant and provides a function to handle the
matched cases.
Example (Matching on a discriminator field)
import { Match, pipe } from "effect"
const match = pipe(
Match.type<
{ type: "A"; a: string } | { type: "B"; b: number } | {
type: "C"
c: boolean
}
>(),
Match.discriminator("type")("A", "B", (_) => `A or B: ${_.type}`),
Match.discriminator("type")("C", (_) => `C(${_.c})`),
Match.exhaustive
)export const const discriminator: <D extends string>(
field: D
) => <
R,
P extends Types.Tags<D, R> & string,
Ret,
Fn extends (_: Extract<R, Record<D, P>>) => Ret
>(
...pattern: [
first: P,
...values: Array<P>,
f: Fn
]
) => <I, F, A, Pr>(
self: Matcher<I, F, R, A, Pr, Ret>
) => Matcher<
I,
Types.AddWithout<F, Extract<R, Record<D, P>>>,
Types.ApplyFilters<
I,
Types.AddWithout<F, Extract<R, Record<D, P>>>
>,
A | ReturnType<Fn>,
Pr,
Ret
>
Matches values based on a specified discriminant field.
When to use
Use to match one or more exact values of a discriminator field.
Details
This function is used to define pattern matching on objects that follow a
discriminated union structure, where a specific field (e.g., type,
kind, _tag) determines the variant of the object. It allows matching
multiple values of the discriminant and provides a function to handle the
matched cases.
Example (Matching on a discriminator field)
import { Match, pipe } from "effect"
const match = pipe(
Match.type<
{ type: "A"; a: string } | { type: "B"; b: number } | {
type: "C"
c: boolean
}
>(),
Match.discriminator("type")("A", "B", (_) => `A or B: ${_.type}`),
Match.discriminator("type")("C", (_) => `C(${_.c})`),
Match.exhaustive
)
discriminator: <function (type parameter) D in <D extends string>(field: D): <R, P extends Types.Tags<D, R> & string, Ret, Fn extends (_: Extract<R, Record<D, P>>) => Ret>(...pattern: [first: P, ...values: Array<P>, f: Fn]) => <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>D extends string>(
field: D extends stringfield: function (type parameter) D in <D extends string>(field: D): <R, P extends Types.Tags<D, R> & string, Ret, Fn extends (_: Extract<R, Record<D, P>>) => Ret>(...pattern: [first: P, ...values: Array<P>, f: Fn]) => <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>D
) => <function (type parameter) R in <R, P extends Types.Tags<D, R> & string, Ret, Fn extends (_: Extract<R, Record<D, P>>) => Ret>(...pattern: [first: P, ...values: Array<P>, f: Fn]): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>R, function (type parameter) P in <R, P extends Types.Tags<D, R> & string, Ret, Fn extends (_: Extract<R, Record<D, P>>) => Ret>(...pattern: [first: P, ...values: Array<P>, f: Fn]): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>P extends Types.type Types.Tags<D extends string, P> = P extends Record<D, infer X> ? X : neverExtracts tag values from a discriminated union based on a discriminant field.
Details
This utility type extracts the possible values of a discriminant field
from a union type. It's used internally to implement tag-based pattern
matching for discriminated unions.
Example (Extracting discriminator tags)
import type { Match } from "effect"
type Events =
| { _tag: "click"; x: number; y: number }
| { _tag: "keypress"; key: string }
| { _tag: "scroll"; delta: number }
type EventTags = Match.Types.Tags<"_tag", Events>
// Result: "click" | "keypress" | "scroll"
type CustomTags = Match.Types.Tags<
"type",
| { type: "user"; name: string }
| { type: "admin"; permissions: Array<string> }
>
// Result: "user" | "admin"
Tags<function (type parameter) D in <D extends string>(field: D): <R, P extends Types.Tags<D, R> & string, Ret, Fn extends (_: Extract<R, Record<D, P>>) => Ret>(...pattern: [first: P, ...values: Array<P>, f: Fn]) => <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>D, function (type parameter) R in <R, P extends Types.Tags<D, R> & string, Ret, Fn extends (_: Extract<R, Record<D, P>>) => Ret>(...pattern: [first: P, ...values: Array<P>, f: Fn]): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>R> & string, function (type parameter) Ret in <R, P extends Types.Tags<D, R> & string, Ret, Fn extends (_: Extract<R, Record<D, P>>) => Ret>(...pattern: [first: P, ...values: Array<P>, f: Fn]): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>Ret, function (type parameter) Fn in <R, P extends Types.Tags<D, R> & string, Ret, Fn extends (_: Extract<R, Record<D, P>>) => Ret>(...pattern: [first: P, ...values: Array<P>, f: Fn]): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>Fn extends (_: Extract<R, Record<D, P>>_: type Extract<T, U> = T extends U
? T
: never
Extract from T those types that are assignable to U
Extract<function (type parameter) R in <R, P extends Types.Tags<D, R> & string, Ret, Fn extends (_: Extract<R, Record<D, P>>) => Ret>(...pattern: [first: P, ...values: Array<P>, f: Fn]): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>R, type Record<K extends keyof any, T> = {
[P in K]: T
}
Construct a type with a set of properties K of type T
Record<function (type parameter) D in <D extends string>(field: D): <R, P extends Types.Tags<D, R> & string, Ret, Fn extends (_: Extract<R, Record<D, P>>) => Ret>(...pattern: [first: P, ...values: Array<P>, f: Fn]) => <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>D, function (type parameter) P in <R, P extends Types.Tags<D, R> & string, Ret, Fn extends (_: Extract<R, Record<D, P>>) => Ret>(...pattern: [first: P, ...values: Array<P>, f: Fn]): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>P>>) => function (type parameter) Ret in <R, P extends Types.Tags<D, R> & string, Ret, Fn extends (_: Extract<R, Record<D, P>>) => Ret>(...pattern: [first: P, ...values: Array<P>, f: Fn]): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>Ret>(
...pattern: [first: P, ...values: P[], f: Fn](parameter) pattern: {
0: P;
length: number;
toString: () => string;
toLocaleString: { (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string };
pop: () => P | Fn | undefined;
push: (...items: Array<P | Fn>) => number;
concat: { (...items: Array<ConcatArray<P | Fn>>): Array<P | Fn>; (...items: Array<P | Fn | ConcatArray<P | Fn>>): Array<P | Fn> };
join: (separator?: string) => string;
reverse: () => Array<P | Fn>;
shift: () => P | Fn | undefined;
slice: (start?: number, end?: number) => Array<P | Fn>;
sort: (compareFn?: ((a: P | Fn, b: P | Fn) => number) | undefined) => [first: P, ...values: P[], f: Fn];
splice: { (start: number, deleteCount?: number): Array<P | Fn>; (start: number, deleteCount: number, ...items: Array<P | Fn>): Array<P | Fn> };
unshift: (...items: Array<P | Fn>) => number;
indexOf: (searchElement: P | Fn, fromIndex?: number) => number;
lastIndexOf: (searchElement: P | Fn, fromIndex?: number) => number;
every: { (predicate: (value: P | Fn, index: number, array: Array<P | Fn>) => value is S, thisArg?: any): this is S[]; (predicate: (value: P | Fn, index: number, array: Array<P | Fn>) => unknown, thisArg?: any): boolean };
some: (predicate: (value: P | Fn, index: number, array: Array<P | Fn>) => unknown, thisArg?: any) => boolean;
forEach: (callbackfn: (value: P | Fn, index: number, array: Array<P | Fn>) => void, thisArg?: any) => void;
map: (callbackfn: (value: P | Fn, index: number, array: Array<P | Fn>) => U, thisArg?: any) => Array<U>;
filter: { (predicate: (value: P | Fn, index: number, array: Array<P | Fn>) => value is S, thisArg?: any): Array<S>; (predicate: (value: P | Fn, index: number, array: Array<P | Fn>) => unknown, thisArg?: any): Array<P | Fn> };
reduce: { (callbackfn: (previousValue: P | Fn, currentValue: P | Fn, currentIndex: number, array: Array<P | Fn>) => P | Fn): P | Fn; (callbackfn: (previousValue: P | Fn, currentValue: P | Fn, currentIndex: number, array: Array<P | Fn>) => P | Fn, …;
reduceRight: { (callbackfn: (previousValue: P | Fn, currentValue: P | Fn, currentIndex: number, array: Array<P | Fn>) => P | Fn): P | Fn; (callbackfn: (previousValue: P | Fn, currentValue: P | Fn, currentIndex: number, array: Array<P | Fn>) => P | Fn, …;
find: { (predicate: (value: P | Fn, index: number, obj: Array<P | Fn>) => value is S, thisArg?: any): S | undefined; (predicate: (value: P | Fn, index: number, obj: Array<P | Fn>) => unknown, thisArg?: any): P | Fn | undefined };
findIndex: (predicate: (value: P | Fn, index: number, obj: Array<P | Fn>) => unknown, thisArg?: any) => number;
fill: (value: P | Fn, start?: number, end?: number) => [first: P, ...values: P[], f: Fn];
copyWithin: (target: number, start: number, end?: number) => [first: P, ...values: P[], f: Fn];
entries: () => ArrayIterator<[number, P | Fn]>;
keys: () => ArrayIterator<number>;
values: () => ArrayIterator<P | Fn>;
includes: (searchElement: P | Fn, fromIndex?: number) => boolean;
flatMap: (callback: (this: This, value: P | Fn, index: number, array: Array<P | Fn>) => U | ReadonlyArray<U>, thisArg?: This | undefined) => Array<U>;
flat: (this: A, depth?: D | undefined) => Array<FlatArray<A, D>>;
at: (index: number) => P | Fn | undefined;
findLast: { (predicate: (value: P | Fn, index: number, array: Array<P | Fn>) => value is S, thisArg?: any): S | undefined; (predicate: (value: P | Fn, index: number, array: Array<P | Fn>) => unknown, thisArg?: any): P | Fn | undefined };
findLastIndex: (predicate: (value: P | Fn, index: number, array: Array<P | Fn>) => unknown, thisArg?: any) => number;
toReversed: () => Array<P | Fn>;
toSorted: (compareFn?: ((a: P | Fn, b: P | Fn) => number) | undefined) => Array<P | Fn>;
toSpliced: { (start: number, deleteCount: number, ...items: Array<P | Fn>): Array<P | Fn>; (start: number, deleteCount?: number): Array<P | Fn> };
with: (index: number, value: P | Fn) => Array<P | Fn>;
}
pattern: [Pfirst: function (type parameter) P in <R, P extends Types.Tags<D, R> & string, Ret, Fn extends (_: Extract<R, Record<D, P>>) => Ret>(...pattern: [first: P, ...values: Array<P>, f: Fn]): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>P, ...values: interface Array<T>Array<function (type parameter) P in <R, P extends Types.Tags<D, R> & string, Ret, Fn extends (_: Extract<R, Record<D, P>>) => Ret>(...pattern: [first: P, ...values: Array<P>, f: Fn]): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>P>, Fnf: function (type parameter) Fn in <R, P extends Types.Tags<D, R> & string, Ret, Fn extends (_: Extract<R, Record<D, P>>) => Ret>(...pattern: [first: P, ...values: Array<P>, f: Fn]): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>Fn]
) => <function (type parameter) I in <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>): Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>I, function (type parameter) F in <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>): Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>F, function (type parameter) A in <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>): Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>A, function (type parameter) Pr in <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>): Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>Pr>(
self: Matcher<I, F, R, A, Pr, Ret>self: type Matcher<
Input,
Filters,
RemainingApplied,
Result,
Provided,
Return = any
> =
| TypeMatcher<
Input,
Filters,
RemainingApplied,
Result,
Return
>
| ValueMatcher<
Input,
Filters,
RemainingApplied,
Result,
Provided,
Return
>
Union type for matchers created by Match.type and Match.value.
Details
A Matcher carries the input type, accumulated filters, remaining cases,
result type, and, for value matchers, the provided value being matched.
Example (Matching string and number values)
import { Match } from "effect"
// Simulated dynamic input that can be a string or a number
const input: string | number = "some input"
// ┌─── string
// ▼
const result = Match.value(input).pipe(
// Match if the value is a number
Match.when(Match.number, (n) => `number: ${n}`),
// Match if the value is a string
Match.when(Match.string, (s) => `string: ${s}`),
// Ensure all possible cases are covered
Match.exhaustive
)
console.log(result)
// Output: "string: some input"
Matcher<function (type parameter) I in <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>): Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>I, function (type parameter) F in <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>): Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>F, function (type parameter) R in <R, P extends Types.Tags<D, R> & string, Ret, Fn extends (_: Extract<R, Record<D, P>>) => Ret>(...pattern: [first: P, ...values: Array<P>, f: Fn]): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>R, function (type parameter) A in <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>): Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>A, function (type parameter) Pr in <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>): Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>Pr, function (type parameter) Ret in <R, P extends Types.Tags<D, R> & string, Ret, Fn extends (_: Extract<R, Record<D, P>>) => Ret>(...pattern: [first: P, ...values: Array<P>, f: Fn]): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>Ret>
) => type Matcher<
Input,
Filters,
RemainingApplied,
Result,
Provided,
Return = any
> =
| TypeMatcher<
Input,
Filters,
RemainingApplied,
Result,
Return
>
| ValueMatcher<
Input,
Filters,
RemainingApplied,
Result,
Provided,
Return
>
Union type for matchers created by Match.type and Match.value.
Details
A Matcher carries the input type, accumulated filters, remaining cases,
result type, and, for value matchers, the provided value being matched.
Example (Matching string and number values)
import { Match } from "effect"
// Simulated dynamic input that can be a string or a number
const input: string | number = "some input"
// ┌─── string
// ▼
const result = Match.value(input).pipe(
// Match if the value is a number
Match.when(Match.number, (n) => `number: ${n}`),
// Match if the value is a string
Match.when(Match.string, (s) => `string: ${s}`),
// Ensure all possible cases are covered
Match.exhaustive
)
console.log(result)
// Output: "string: some input"
Matcher<
function (type parameter) I in <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>): Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>I,
Types.type Types.AddWithout<A, X> = [A] extends [Types.Without<infer WX>] ? Types.Without<X | WX> : [A] extends [Types.Only<infer OX>] ? Types.Only<Exclude<OX, X>> : neverAdds a type to the exclusion filter, expanding what should be filtered out.
Details
This utility type manages the accumulation of excluded types during
pattern matching. When multiple exclusions are applied, it combines
them into a single filter representation.
Example (Accumulating excluded types)
import { Match } from "effect"
// AddWithout is used when combining multiple exclusions:
Match.type<string | number | boolean | null>().pipe(
Match.not(Match.string, () => "not string"),
Match.not(Match.number, () => "not number"),
// Type system uses AddWithout to combine exclusions
Match.orElse(() => "was string or number")
)
AddWithout<function (type parameter) F in <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>): Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>F, type Extract<T, U> = T extends U
? T
: never
Extract from T those types that are assignable to U
Extract<function (type parameter) R in <R, P extends Types.Tags<D, R> & string, Ret, Fn extends (_: Extract<R, Record<D, P>>) => Ret>(...pattern: [first: P, ...values: Array<P>, f: Fn]): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>R, type Record<K extends keyof any, T> = {
[P in K]: T
}
Construct a type with a set of properties K of type T
Record<function (type parameter) D in <D extends string>(field: D): <R, P extends Types.Tags<D, R> & string, Ret, Fn extends (_: Extract<R, Record<D, P>>) => Ret>(...pattern: [first: P, ...values: Array<P>, f: Fn]) => <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>D, function (type parameter) P in <R, P extends Types.Tags<D, R> & string, Ret, Fn extends (_: Extract<R, Record<D, P>>) => Ret>(...pattern: [first: P, ...values: Array<P>, f: Fn]): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>P>>>,
Types.type Types.ApplyFilters<I, A> = A extends Types.Only<infer X> ? X : A extends Types.Without<infer X> ? Exclude<I, X> : neverApplies accumulated filters to an input type, producing the final narrowed type.
Details
This utility type takes the collected inclusion/exclusion filters and
applies them to the input type to compute the final narrowed result.
It's the culmination of the type-level filtering process.
Example (Applying accumulated filters)
import type { Match } from "effect"
// ApplyFilters computes the final narrowed type:
type Result = Match.Types.ApplyFilters<
string | number | boolean,
Match.Types.Only<string>
>
// Result: string
type ExclusionResult = Match.Types.ApplyFilters<
string | number | boolean,
Match.Types.Without<string>
>
// Result: number | boolean
ApplyFilters<function (type parameter) I in <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>): Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>I, Types.type Types.AddWithout<A, X> = [A] extends [Types.Without<infer WX>] ? Types.Without<X | WX> : [A] extends [Types.Only<infer OX>] ? Types.Only<Exclude<OX, X>> : neverAdds a type to the exclusion filter, expanding what should be filtered out.
Details
This utility type manages the accumulation of excluded types during
pattern matching. When multiple exclusions are applied, it combines
them into a single filter representation.
Example (Accumulating excluded types)
import { Match } from "effect"
// AddWithout is used when combining multiple exclusions:
Match.type<string | number | boolean | null>().pipe(
Match.not(Match.string, () => "not string"),
Match.not(Match.number, () => "not number"),
// Type system uses AddWithout to combine exclusions
Match.orElse(() => "was string or number")
)
AddWithout<function (type parameter) F in <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>): Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>F, type Extract<T, U> = T extends U
? T
: never
Extract from T those types that are assignable to U
Extract<function (type parameter) R in <R, P extends Types.Tags<D, R> & string, Ret, Fn extends (_: Extract<R, Record<D, P>>) => Ret>(...pattern: [first: P, ...values: Array<P>, f: Fn]): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>R, type Record<K extends keyof any, T> = {
[P in K]: T
}
Construct a type with a set of properties K of type T
Record<function (type parameter) D in <D extends string>(field: D): <R, P extends Types.Tags<D, R> & string, Ret, Fn extends (_: Extract<R, Record<D, P>>) => Ret>(...pattern: [first: P, ...values: Array<P>, f: Fn]) => <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>D, function (type parameter) P in <R, P extends Types.Tags<D, R> & string, Ret, Fn extends (_: Extract<R, Record<D, P>>) => Ret>(...pattern: [first: P, ...values: Array<P>, f: Fn]): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>P>>>>,
function (type parameter) A in <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>): Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>A | type ReturnType<
T extends (...args: any) => any
> = T extends (...args: any) => infer R ? R : any
Obtain the return type of a function type
ReturnType<function (type parameter) Fn in <R, P extends Types.Tags<D, R> & string, Ret, Fn extends (_: Extract<R, Record<D, P>>) => Ret>(...pattern: [first: P, ...values: Array<P>, f: Fn]): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>Fn>,
function (type parameter) Pr in <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>): Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>Pr,
function (type parameter) Ret in <R, P extends Types.Tags<D, R> & string, Ret, Fn extends (_: Extract<R, Record<D, P>>) => Ret>(...pattern: [first: P, ...values: Array<P>, f: Fn]): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => Matcher<I, Types.AddWithout<F, Extract<R, Record<D, P>>>, Types.ApplyFilters<I, Types.AddWithout<F, Extract<R, Record<D, P>>>>, A | ReturnType<Fn>, Pr, Ret>Ret
> = import internalinternal.const discriminator: <D extends string>(
field: D
) => <
R,
P extends Types.Tags<D, R> & string,
Ret,
Fn extends (_: Extract<R, Record<D, P>>) => Ret
>(
...pattern: [
first: P,
...values: Array<P>,
f: Fn
]
) => <I, F, A, Pr>(
self: Matcher<I, F, R, A, Pr, Ret>
) => Matcher<
I,
Types.AddWithout<F, Extract<R, Record<D, P>>>,
Types.ApplyFilters<
I,
Types.AddWithout<F, Extract<R, Record<D, P>>>
>,
A | ReturnType<Fn>,
Pr,
Ret
>
discriminator