<
R,
Ret,
P extends {
readonly [Tag in Types.Tags<"_tag", R> & string]: (
_: Extract<R, Record<"_tag", Tag>>
) => Ret
} & { readonly [Tag in Exclude<keyof P, Types.Tags<"_tag", R>>]: never }
>(
fields: P
): <I, F, A, Pr>(
self: Matcher<I, F, R, A, Pr, Ret>
) => [Pr] extends [never]
? (u: I) => Unify<A | ReturnType<P[keyof P]>>
: Unify<A | ReturnType<P[keyof P]>>Matches values based on their _tag field and requires handling of all
possible cases.
Details
This function is designed for discriminated unions where every possible
_tag value must have a corresponding handler. Unlike tags, this
function ensures exhaustiveness, meaning all cases must be explicitly
handled. If a _tag value is missing from the mapping, TypeScript will
report an error.
Example (Handling all tag cases)
import { Match, pipe } from "effect"
const match = pipe(
Match.type<
{ _tag: "A"; a: string } | { _tag: "B"; b: number } | {
_tag: "C"
c: boolean
}
>(),
Match.tagsExhaustive({
A: (a) => a.a,
B: (b) => b.b,
C: (c) => c.c
})
)export const const tagsExhaustive: <
R,
Ret,
P extends {
readonly [Tag in Types.Tags<"_tag", R> &
string]: (
_: Extract<R, Record<"_tag", Tag>>
) => Ret
} & {
readonly [Tag in Exclude<
keyof P,
Types.Tags<"_tag", R>
>]: never
}
>(
fields: P
) => <I, F, A, Pr>(
self: Matcher<I, F, R, A, Pr, Ret>
) => [Pr] extends [never]
? (u: I) => Unify<A | ReturnType<P[keyof P]>>
: Unify<A | ReturnType<P[keyof P]>>
Matches values based on their _tag field and requires handling of all
possible cases.
Details
This function is designed for discriminated unions where every possible
_tag value must have a corresponding handler. Unlike
tags
, this
function ensures exhaustiveness, meaning all cases must be explicitly
handled. If a _tag value is missing from the mapping, TypeScript will
report an error.
Example (Handling all tag cases)
import { Match, pipe } from "effect"
const match = pipe(
Match.type<
{ _tag: "A"; a: string } | { _tag: "B"; b: number } | {
_tag: "C"
c: boolean
}
>(),
Match.tagsExhaustive({
A: (a) => a.a,
B: (b) => b.b,
C: (c) => c.c
})
)
tagsExhaustive: <
function (type parameter) R in <R, Ret, P extends { readonly [Tag in Types.Tags<"_tag", R> & string]: (_: Extract<R, Record<"_tag", Tag>>) => Ret; } & { readonly [Tag in Exclude<keyof P, Types.Tags<"_tag", R>>]: never; }>(fields: P): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>R,
function (type parameter) Ret in <R, Ret, P extends { readonly [Tag in Types.Tags<"_tag", R> & string]: (_: Extract<R, Record<"_tag", Tag>>) => Ret; } & { readonly [Tag in Exclude<keyof P, Types.Tags<"_tag", R>>]: never; }>(fields: P): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>Ret,
function (type parameter) P in <R, Ret, P extends { readonly [Tag in Types.Tags<"_tag", R> & string]: (_: Extract<R, Record<"_tag", Tag>>) => Ret; } & { readonly [Tag in Exclude<keyof P, Types.Tags<"_tag", R>>]: never; }>(fields: P): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>P extends
& { readonly [function (type parameter) TagTag in 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<"_tag", function (type parameter) R in <R, Ret, P extends { readonly [Tag in Types.Tags<"_tag", R> & string]: (_: Extract<R, Record<"_tag", Tag>>) => Ret; } & { readonly [Tag in Exclude<keyof P, Types.Tags<"_tag", R>>]: never; }>(fields: P): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>R> & string]: (_: Extract<R, Record<"_tag", Tag>>_: 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, Ret, P extends { readonly [Tag in Types.Tags<"_tag", R> & string]: (_: Extract<R, Record<"_tag", Tag>>) => Ret; } & { readonly [Tag in Exclude<keyof P, Types.Tags<"_tag", R>>]: never; }>(fields: P): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>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<"_tag", function (type parameter) TagTag>>) => function (type parameter) Ret in <R, Ret, P extends { readonly [Tag in Types.Tags<"_tag", R> & string]: (_: Extract<R, Record<"_tag", Tag>>) => Ret; } & { readonly [Tag in Exclude<keyof P, Types.Tags<"_tag", R>>]: never; }>(fields: P): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>Ret }
& { readonly [function (type parameter) TagTag in type Exclude<T, U> = T extends U
? never
: T
Exclude from T those types that are assignable to U
Exclude<keyof function (type parameter) P in <R, Ret, P extends { readonly [Tag in Types.Tags<"_tag", R> & string]: (_: Extract<R, Record<"_tag", Tag>>) => Ret; } & { readonly [Tag in Exclude<keyof P, Types.Tags<"_tag", R>>]: never; }>(fields: P): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>P, 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<"_tag", function (type parameter) R in <R, Ret, P extends { readonly [Tag in Types.Tags<"_tag", R> & string]: (_: Extract<R, Record<"_tag", Tag>>) => Ret; } & { readonly [Tag in Exclude<keyof P, Types.Tags<"_tag", R>>]: never; }>(fields: P): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>R>>]: never }
>(
fields: P extends { readonly [Tag in Types.Tags<"_tag", R> & string]: (_: Extract<R, Record<"_tag", Tag>>) => Ret; } & { readonly [Tag in Exclude<keyof P, Types.Tags<"_tag", R>>]: never; }fields: function (type parameter) P in <R, Ret, P extends { readonly [Tag in Types.Tags<"_tag", R> & string]: (_: Extract<R, Record<"_tag", Tag>>) => Ret; } & { readonly [Tag in Exclude<keyof P, Types.Tags<"_tag", R>>]: never; }>(fields: P): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>P
) => <function (type parameter) I in <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>I, function (type parameter) F in <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>F, function (type parameter) A in <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>A, function (type parameter) Pr in <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>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>): [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>I, function (type parameter) F in <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>F, function (type parameter) R in <R, Ret, P extends { readonly [Tag in Types.Tags<"_tag", R> & string]: (_: Extract<R, Record<"_tag", Tag>>) => Ret; } & { readonly [Tag in Exclude<keyof P, Types.Tags<"_tag", R>>]: never; }>(fields: P): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>R, function (type parameter) A in <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>A, function (type parameter) Pr in <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>Pr, function (type parameter) Ret in <R, Ret, P extends { readonly [Tag in Types.Tags<"_tag", R> & string]: (_: Extract<R, Record<"_tag", Tag>>) => Ret; } & { readonly [Tag in Exclude<keyof P, Types.Tags<"_tag", R>>]: never; }>(fields: P): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>Ret>
) => [function (type parameter) Pr in <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>Pr] extends [never] ? (u: Iu: function (type parameter) I in <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>I) => type Unify<A> = Values<ExtractTypes<FilterIn<A> & {
[typeSymbol]: A;
}>> extends infer Z ? Z | FilterInUnmatched<A, Keys<ExtractTypes<FilterIn<A> & {
[typeSymbol]: A;
}>>> | FilterOut<A> : never
Unifies types that implement the unification protocol.
When to use
Use to normalize unions of types that expose Effect's unification protocol.
Details
This type performs automatic type unification for types that contain
the unification symbols (unifySymbol, typeSymbol, ignoreSymbol).
It's primarily used internally by the Effect type system to handle
complex type unions and provide better type inference.
Example (Unifying protocol types)
import type { Unify } from "effect"
// Example of types that can be unified
type UnifiableA = {
value: string
[Unify.typeSymbol]?: string
[Unify.unifySymbol]?: { String: () => string }
}
type UnifiableB = {
value: number
[Unify.typeSymbol]?: number
[Unify.unifySymbol]?: { Number: () => number }
}
// Unify automatically handles the union
type Unified = Unify.Unify<UnifiableA | UnifiableB>
// Results in a properly unified type
Unify<function (type parameter) A in <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>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) P in <R, Ret, P extends { readonly [Tag in Types.Tags<"_tag", R> & string]: (_: Extract<R, Record<"_tag", Tag>>) => Ret; } & { readonly [Tag in Exclude<keyof P, Types.Tags<"_tag", R>>]: never; }>(fields: P): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>P[keyof function (type parameter) P in <R, Ret, P extends { readonly [Tag in Types.Tags<"_tag", R> & string]: (_: Extract<R, Record<"_tag", Tag>>) => Ret; } & { readonly [Tag in Exclude<keyof P, Types.Tags<"_tag", R>>]: never; }>(fields: P): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>P]>> : type Unify<A> = Values<ExtractTypes<FilterIn<A> & {
[typeSymbol]: A;
}>> extends infer Z ? Z | FilterInUnmatched<A, Keys<ExtractTypes<FilterIn<A> & {
[typeSymbol]: A;
}>>> | FilterOut<A> : never
Unifies types that implement the unification protocol.
When to use
Use to normalize unions of types that expose Effect's unification protocol.
Details
This type performs automatic type unification for types that contain
the unification symbols (unifySymbol, typeSymbol, ignoreSymbol).
It's primarily used internally by the Effect type system to handle
complex type unions and provide better type inference.
Example (Unifying protocol types)
import type { Unify } from "effect"
// Example of types that can be unified
type UnifiableA = {
value: string
[Unify.typeSymbol]?: string
[Unify.unifySymbol]?: { String: () => string }
}
type UnifiableB = {
value: number
[Unify.typeSymbol]?: number
[Unify.unifySymbol]?: { Number: () => number }
}
// Unify automatically handles the union
type Unified = Unify.Unify<UnifiableA | UnifiableB>
// Results in a properly unified type
Unify<function (type parameter) A in <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>): [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>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) P in <R, Ret, P extends { readonly [Tag in Types.Tags<"_tag", R> & string]: (_: Extract<R, Record<"_tag", Tag>>) => Ret; } & { readonly [Tag in Exclude<keyof P, Types.Tags<"_tag", R>>]: never; }>(fields: P): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>P[keyof function (type parameter) P in <R, Ret, P extends { readonly [Tag in Types.Tags<"_tag", R> & string]: (_: Extract<R, Record<"_tag", Tag>>) => Ret; } & { readonly [Tag in Exclude<keyof P, Types.Tags<"_tag", R>>]: never; }>(fields: P): <I, F, A, Pr>(self: Matcher<I, F, R, A, Pr, Ret>) => [Pr] extends [never] ? (u: I) => Unify<A | ReturnType<P[keyof P]>> : Unify<A | ReturnType<P[keyof P]>>P]>> =
import internalinternal.const tagsExhaustive: <
R,
Ret,
P extends {
readonly [Tag in Types.Tags<"_tag", R> &
string]: (
_: Extract<R, Record<"_tag", Tag>>
) => Ret
} & {
readonly [Tag in Exclude<
keyof P,
Types.Tags<"_tag", R>
>]: never
}
>(
fields: P
) => <I, F, A, Pr>(
self: Matcher<I, F, R, A, Pr, Ret>
) => [Pr] extends [never]
? (u: I) => Unify<A | ReturnType<P[keyof P]>>
: Unify<A | ReturnType<P[keyof P]>>
tagsExhaustive