TaggedEnum<A>Transforms a record of variant definitions into a discriminated union type.
When to use
Use when you have two or more variants that share a common _tag discriminator.
Details
Each key in the record becomes a variant with readonly _tag set to that
key. Use with taggedEnum to get constructors and matchers.
Gotchas
Variant records must not include a _tag property; it is added automatically.
Example (Defining a tagged enum)
import { Data } from "effect"
type HttpError = Data.TaggedEnum<{
BadRequest: { readonly status: 400; readonly message: string }
NotFound: { readonly status: 404 }
}>
// Equivalent to:
// | { readonly _tag: "BadRequest"; readonly status: 400; readonly message: string }
// | { readonly _tag: "NotFound"; readonly status: 404 }
const { BadRequest, NotFound } = Data.taggedEnum<HttpError>()
const err = BadRequest({ status: 400, message: "missing id" })
console.log(err._tag)
// "BadRequest"export type type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>> = keyof A extends infer Tag ? Tag extends keyof A ? Types.Simplify<{
readonly _tag: Tag;
} & { readonly [K in keyof A[Tag]]: A[Tag][K]; }> : never : never
Transforms a record of variant definitions into a discriminated union type.
When to use
Use when you have two or more variants that share a common _tag discriminator.
Details
Each key in the record becomes a variant with readonly _tag set to that
key. Use with
taggedEnum
to get constructors and matchers.
Gotchas
Variant records must not include a _tag property; it is added automatically.
Example (Defining a tagged enum)
import { Data } from "effect"
type HttpError = Data.TaggedEnum<{
BadRequest: { readonly status: 400; readonly message: string }
NotFound: { readonly status: 404 }
}>
// Equivalent to:
// | { readonly _tag: "BadRequest"; readonly status: 400; readonly message: string }
// | { readonly _tag: "NotFound"; readonly status: 404 }
const { BadRequest, NotFound } = Data.taggedEnum<HttpError>()
const err = BadRequest({ status: 400, message: "missing id" })
console.log(err._tag)
// "BadRequest"
Namespace for TaggedEnum utility types.
When to use
Use to reference utility types for constructing, extracting, and matching
TaggedEnum variants.
Details
Provides helper types for:
- Generic tagged enums (
TaggedEnum.WithGenerics
,
TaggedEnum.Kind
)
- Extracting constructor arguments (
TaggedEnum.Args
) and variant
values (
TaggedEnum.Value
)
- Full constructor objects (
TaggedEnum.Constructor
)
TaggedEnum<
function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>A extends type Record<K extends keyof any, T> = {
[P in K]: T
}
Construct a type with a set of properties K of type T
Record<string, type Record<K extends keyof any, T> = {
[P in K]: T
}
Construct a type with a set of properties K of type T
Record<string, any>> & type UntaggedChildren<A> =
true extends ChildrenAreTagged<A>
? "It looks like you're trying to create a tagged enum, but one or more of its members already has a `_tag` property."
: unknown
UntaggedChildren<function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>A>
> = keyof function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>A extends infer function (type parameter) TagTag ? function (type parameter) TagTag extends keyof function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>A ? import TypesTypes.type Simplify<A> = {
[K in keyof A]: A[K]
} extends infer B
? B
: never
Flattens an intersection type into a single object type for readability.
When to use
Use to clean up IDE tooltips that show A & B & C instead of a merged
object.
Details
Does not change the type semantically, only its display.
Example (Simplifying an intersection)
import type { Types } from "effect"
// Without Simplify: IDE shows { a: number } & { b: string }
// With Simplify: IDE shows { a: number; b: string }
type Clean = Types.Simplify<{ a: number } & { b: string }>
Simplify<
{ readonly _tag: Tag_tag: function (type parameter) TagTag } & { readonly [function (type parameter) KK in keyof function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>A[function (type parameter) TagTag]]: function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>A[function (type parameter) TagTag][function (type parameter) KK] }
>
: never
: never
type type ChildrenAreTagged<A> =
keyof A extends infer K
? K extends keyof A
? "_tag" extends keyof A[K]
? true
: false
: never
: never
ChildrenAreTagged<function (type parameter) A in type ChildrenAreTagged<A>A> = keyof function (type parameter) A in type ChildrenAreTagged<A>A extends infer function (type parameter) KK ? function (type parameter) KK extends keyof function (type parameter) A in type ChildrenAreTagged<A>A ? "_tag" extends keyof function (type parameter) A in type ChildrenAreTagged<A>A[function (type parameter) KK] ? true
: false
: never
: never
type type UntaggedChildren<A> =
true extends ChildrenAreTagged<A>
? "It looks like you're trying to create a tagged enum, but one or more of its members already has a `_tag` property."
: unknown
UntaggedChildren<function (type parameter) A in type UntaggedChildren<A>A> = true extends type ChildrenAreTagged<A> =
keyof A extends infer K
? K extends keyof A
? "_tag" extends keyof A[K]
? true
: false
: never
: never
ChildrenAreTagged<function (type parameter) A in type UntaggedChildren<A>A>
? "It looks like you're trying to create a tagged enum, but one or more of its members already has a `_tag` property."
: unknown
/**
* Namespace for `TaggedEnum` utility types.
*
* **When to use**
*
* Use to reference utility types for constructing, extracting, and matching
* `TaggedEnum` variants.
*
* **Details**
*
* Provides helper types for:
* - Generic tagged enums ({@link TaggedEnum.WithGenerics}, {@link TaggedEnum.Kind})
* - Extracting constructor arguments ({@link TaggedEnum.Args}) and variant
* values ({@link TaggedEnum.Value})
* - Full constructor objects ({@link TaggedEnum.Constructor})
*
* @since 2.0.0
*/
export declare namespace TaggedEnum {
/**
* Defines a tagged enum shape that accepts generic type parameters.
*
* **When to use**
*
* Use when variant payloads need to be parameterized, such as `Result<E, A>`.
*
* **Details**
*
* Extend this interface and set `taggedEnum` to your union type, using
* `this["A"]`, `this["B"]`, etc. as placeholders for the generics. The
* `Count` parameter declares how many generics are used (up to 4).
*
* **Example** (Defining a generic tagged enum)
*
* ```ts
* import { Data } from "effect"
*
* type MyResult<E, A> = Data.TaggedEnum<{
* Failure: { readonly error: E }
* Success: { readonly value: A }
* }>
*
* interface MyResultDef extends Data.TaggedEnum.WithGenerics<2> {
* readonly taggedEnum: MyResult<this["A"], this["B"]>
* }
*
* const { Failure, Success } = Data.taggedEnum<MyResultDef>()
*
* const ok = Success({ value: 42 })
* // ok: { readonly _tag: "Success"; readonly value: number }
* ```
*
* @see {@link Kind} — apply concrete types to a `WithGenerics` definition
* @see {@link taggedEnum} — constructors and matchers
*
* @category models
* @since 2.0.0
*/
export interface interface TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.WithGenerics<Count extends number>Defines a tagged enum shape that accepts generic type parameters.
When to use
Use when variant payloads need to be parameterized, such as Result<E, A>.
Details
Extend this interface and set taggedEnum to your union type, using
this["A"], this["B"], etc. as placeholders for the generics. The
Count parameter declares how many generics are used (up to 4).
Example (Defining a generic tagged enum)
import { Data } from "effect"
type MyResult<E, A> = Data.TaggedEnum<{
Failure: { readonly error: E }
Success: { readonly value: A }
}>
interface MyResultDef extends Data.TaggedEnum.WithGenerics<2> {
readonly taggedEnum: MyResult<this["A"], this["B"]>
}
const { Failure, Success } = Data.taggedEnum<MyResultDef>()
const ok = Success({ value: 42 })
// ok: { readonly _tag: "Success"; readonly value: number }
WithGenerics<function (type parameter) Count in WithGenerics<Count extends number>Count extends number> {
readonly TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.WithGenerics<Count extends number>.taggedEnum: {
readonly _tag: string;
}
taggedEnum: { readonly _tag: string_tag: string }
readonly TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.WithGenerics<Count extends number>.numberOfGenerics: Count extends numbernumberOfGenerics: function (type parameter) Count in WithGenerics<Count extends number>Count
readonly TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.WithGenerics<Count extends number>.A: unknownA: unknown
readonly TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.WithGenerics<Count extends number>.B: unknownB: unknown
readonly TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.WithGenerics<Count extends number>.C: unknownC: unknown
readonly TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.WithGenerics<Count extends number>.D: unknownD: unknown
}
/**
* Applies concrete type arguments to a `WithGenerics` definition, producing
* the resulting tagged union type.
*
* **When to use**
*
* Use to refer to a specific instantiation of a generic tagged enum in type signatures.
*
* **Example** (Applying generics)
*
* ```ts
* import type { Data } from "effect"
*
* type Option<A> = Data.TaggedEnum<{
* None: {}
* Some: { readonly value: A }
* }>
* interface OptionDef extends Data.TaggedEnum.WithGenerics<1> {
* readonly taggedEnum: Option<this["A"]>
* }
*
* // Resolve to the concrete union for `string`
* type StringOption = Data.TaggedEnum.Kind<OptionDef, string>
* // { _tag: "None" } | { _tag: "Some"; value: string }
* ```
*
* @see {@link WithGenerics} — define the generic shape
*
* @category utility types
* @since 2.0.0
*/
export type type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Kind<Z extends TaggedEnum.WithGenerics<number>, A = unknown, B = unknown, C = unknown, D = unknown> = (Z & {
readonly A: A;
readonly B: B;
readonly C: C;
readonly D: D;
})["taggedEnum"]
Applies concrete type arguments to a WithGenerics definition, producing
the resulting tagged union type.
When to use
Use to refer to a specific instantiation of a generic tagged enum in type signatures.
Example (Applying generics)
import type { Data } from "effect"
type Option<A> = Data.TaggedEnum<{
None: {}
Some: { readonly value: A }
}>
interface OptionDef extends Data.TaggedEnum.WithGenerics<1> {
readonly taggedEnum: Option<this["A"]>
}
// Resolve to the concrete union for `string`
type StringOption = Data.TaggedEnum.Kind<OptionDef, string>
// { _tag: "None" } | { _tag: "Some"; value: string }
Kind<
function (type parameter) Z in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Kind<Z extends TaggedEnum.WithGenerics<number>, A = unknown, B = unknown, C = unknown, D = unknown>Z extends interface TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.WithGenerics<Count extends number>Defines a tagged enum shape that accepts generic type parameters.
When to use
Use when variant payloads need to be parameterized, such as Result<E, A>.
Details
Extend this interface and set taggedEnum to your union type, using
this["A"], this["B"], etc. as placeholders for the generics. The
Count parameter declares how many generics are used (up to 4).
Example (Defining a generic tagged enum)
import { Data } from "effect"
type MyResult<E, A> = Data.TaggedEnum<{
Failure: { readonly error: E }
Success: { readonly value: A }
}>
interface MyResultDef extends Data.TaggedEnum.WithGenerics<2> {
readonly taggedEnum: MyResult<this["A"], this["B"]>
}
const { Failure, Success } = Data.taggedEnum<MyResultDef>()
const ok = Success({ value: 42 })
// ok: { readonly _tag: "Success"; readonly value: number }
WithGenerics<number>,
function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Kind<Z extends TaggedEnum.WithGenerics<number>, A = unknown, B = unknown, C = unknown, D = unknown>A = unknown,
function (type parameter) B in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Kind<Z extends TaggedEnum.WithGenerics<number>, A = unknown, B = unknown, C = unknown, D = unknown>B = unknown,
function (type parameter) C in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Kind<Z extends TaggedEnum.WithGenerics<number>, A = unknown, B = unknown, C = unknown, D = unknown>C = unknown,
function (type parameter) D in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Kind<Z extends TaggedEnum.WithGenerics<number>, A = unknown, B = unknown, C = unknown, D = unknown>D = unknown
> = (function (type parameter) Z in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Kind<Z extends TaggedEnum.WithGenerics<number>, A = unknown, B = unknown, C = unknown, D = unknown>Z & {
readonly type A: A = unknownA: function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Kind<Z extends TaggedEnum.WithGenerics<number>, A = unknown, B = unknown, C = unknown, D = unknown>A
readonly type B: B = unknownB: function (type parameter) B in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Kind<Z extends TaggedEnum.WithGenerics<number>, A = unknown, B = unknown, C = unknown, D = unknown>B
readonly type C: C = unknownC: function (type parameter) C in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Kind<Z extends TaggedEnum.WithGenerics<number>, A = unknown, B = unknown, C = unknown, D = unknown>C
readonly type D: D = unknownD: function (type parameter) D in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Kind<Z extends TaggedEnum.WithGenerics<number>, A = unknown, B = unknown, C = unknown, D = unknown>D
})["taggedEnum"]
/**
* Extracts the constructor argument type for a specific variant of a tagged
* union.
*
* **When to use**
*
* Use to derive the argument object expected by a constructor for one tagged
* union variant.
*
* **Details**
*
* Returns `void` if the variant has no fields beyond `_tag`.
*
* **Example** (Extracting variant args)
*
* ```ts
* import type { Data } from "effect"
*
* type Result =
* | { readonly _tag: "Ok"; readonly value: number }
* | { readonly _tag: "Err"; readonly error: string }
*
* type OkArgs = Data.TaggedEnum.Args<Result, "Ok">
* // { readonly value: number }
*
* type ErrArgs = Data.TaggedEnum.Args<Result, "Err">
* // { readonly error: string }
* ```
*
* @see {@link Value} — extracts the full variant type (including `_tag`)
*
* @category utility types
* @since 2.0.0
*/
export type type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Args<A extends { readonly _tag: string; }, K extends A["_tag"], E = Extract<A, { readonly _tag: K; }>> = { readonly [K in keyof E as K extends "_tag" ? never : K]: E[K]; } extends infer T ? Types.VoidIfEmpty<T> : neverExtracts the constructor argument type for a specific variant of a tagged
union.
When to use
Use to derive the argument object expected by a constructor for one tagged
union variant.
Details
Returns void if the variant has no fields beyond _tag.
Example (Extracting variant args)
import type { Data } from "effect"
type Result =
| { readonly _tag: "Ok"; readonly value: number }
| { readonly _tag: "Err"; readonly error: string }
type OkArgs = Data.TaggedEnum.Args<Result, "Ok">
// { readonly value: number }
type ErrArgs = Data.TaggedEnum.Args<Result, "Err">
// { readonly error: string }
Args<
function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Args<A extends { readonly _tag: string; }, K extends A["_tag"], E = Extract<A, { readonly _tag: K; }>>A extends { readonly _tag: string_tag: string },
function (type parameter) K in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Args<A extends { readonly _tag: string; }, K extends A["_tag"], E = Extract<A, { readonly _tag: K; }>>K extends function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Args<A extends { readonly _tag: string; }, K extends A["_tag"], E = Extract<A, { readonly _tag: K; }>>A["_tag"],
function (type parameter) E in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Args<A extends { readonly _tag: string; }, K extends A["_tag"], E = Extract<A, { readonly _tag: K; }>>E = type Extract<T, U> = T extends U
? T
: never
Extract from T those types that are assignable to U
Extract<function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Args<A extends { readonly _tag: string; }, K extends A["_tag"], E = Extract<A, { readonly _tag: K; }>>A, { readonly _tag: K extends A["_tag"]_tag: function (type parameter) K in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Args<A extends { readonly _tag: string; }, K extends A["_tag"], E = Extract<A, { readonly _tag: K; }>>K }>
> = {
readonly [function (type parameter) KK in keyof function (type parameter) E in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Args<A extends { readonly _tag: string; }, K extends A["_tag"], E = Extract<A, { readonly _tag: K; }>>E as function (type parameter) KK extends "_tag" ? never : function (type parameter) KK]: function (type parameter) E in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Args<A extends { readonly _tag: string; }, K extends A["_tag"], E = Extract<A, { readonly _tag: K; }>>E[function (type parameter) KK]
} extends infer function (type parameter) TT ? import TypesTypes.type VoidIfEmpty<S> =
keyof S extends never ? void : S
Conditional type that returns void if S is an empty object type,
otherwise returns S.
When to use
Use to erase an empty object type from an API result or parameter position.
VoidIfEmpty<function (type parameter) TT>
: never
/**
* Extracts the full variant type (including `_tag`) for a specific tag.
*
* **When to use**
*
* Use to select one full tagged-union variant by its `_tag` value.
*
* **Example** (Extracting a variant type)
*
* ```ts
* import type { Data } from "effect"
*
* type Result =
* | { readonly _tag: "Ok"; readonly value: number }
* | { readonly _tag: "Err"; readonly error: string }
*
* type OkVariant = Data.TaggedEnum.Value<Result, "Ok">
* // { readonly _tag: "Ok"; readonly value: number }
* ```
*
* @see {@link Args} — extracts fields without `_tag`
*
* @category utility types
* @since 2.0.0
*/
export type type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Value<A extends { readonly _tag: string; }, K extends A["_tag"]> = A extends {
readonly _tag: K;
} ? A : never
Extracts the full variant type (including _tag) for a specific tag.
When to use
Use to select one full tagged-union variant by its _tag value.
Example (Extracting a variant type)
import type { Data } from "effect"
type Result =
| { readonly _tag: "Ok"; readonly value: number }
| { readonly _tag: "Err"; readonly error: string }
type OkVariant = Data.TaggedEnum.Value<Result, "Ok">
// { readonly _tag: "Ok"; readonly value: number }
Value<
function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Value<A extends { readonly _tag: string; }, K extends A["_tag"]>A extends { readonly _tag: string_tag: string },
function (type parameter) K in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Value<A extends { readonly _tag: string; }, K extends A["_tag"]>K extends function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Value<A extends { readonly _tag: string; }, K extends A["_tag"]>A["_tag"]
> = type Extract<T, U> = T extends U
? T
: never
Extract from T those types that are assignable to U
Extract<function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Value<A extends { readonly _tag: string; }, K extends A["_tag"]>A, { readonly _tag: K extends A["_tag"]_tag: function (type parameter) K in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Value<A extends { readonly _tag: string; }, K extends A["_tag"]>K }>
/**
* The full constructors-and-matchers object type returned by {@link taggedEnum}.
*
* **When to use**
*
* Use when you want to annotate an exported constructor bundle so downstream
* code keeps exact variant constructors and exhaustive matching.
*
* **Details**
*
* Includes:
* - A constructor function for each variant (keyed by tag name)
* - `$is(tag)` — returns a type-guard that checks only the `_tag` field;
* safe when the tag is globally unique and the value was produced by your
* constructors. For untrusted input, validate with the `Schema` module first.
* - `$match` — exhaustive pattern matching (data-last or data-first)
*
* **Example** (Using the constructor object)
*
* ```ts
* import { Data } from "effect"
*
* type Shape =
* | { readonly _tag: "Circle"; readonly radius: number }
* | { readonly _tag: "Rect"; readonly w: number; readonly h: number }
*
* const { Circle, Rect, $is, $match } = Data.taggedEnum<Shape>()
*
* const shape = Circle({ radius: 10 })
*
* // Type guard
* if ($is("Circle")(shape)) {
* console.log(shape.radius)
* }
*
* // Pattern matching
* const label = $match(shape, {
* Circle: (s) => `circle r=${s.radius}`,
* Rect: (s) => `rect ${s.w}x${s.h}`
* })
* ```
*
* @see {@link taggedEnum} — creates constructors and matchers
*
* @category types
* @since 3.1.0
*/
export type type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Constructor<A extends { readonly _tag: string; }> = { [K in keyof ({ readonly [Tag in A["_tag"]]: ConstructorFrom<Extract<A, {
readonly _tag: Tag;
}>, "_tag">; } & {
readonly $is: <Tag extends A["_tag"]>(tag: Tag) => (u: unknown) => u is Extract<A, {
readonly _tag: Tag;
}>;
readonly $match: {
<Cases extends { readonly [Tag in A["_tag"]]: (args: Extract<A, {
readonly _tag: Tag;
}>) => any; }>(cases: Cases): (value: A) => Unify<ReturnType<Cases[A["_tag"]]>>;
<Cases extends { readonly [Tag in A["_tag"]]: (args: Extract<A, {
readonly _tag: Tag;
}>) => any; }>(value: A, cases: Cases): Unify<ReturnType<Cases[A["_tag"]]>>;
};
})]: ({ readonly [Tag in A["_tag"]]: ConstructorFrom<Extract<A, {
readonly _tag: Tag;
}>, "_tag">; } & {
readonly $is: <Tag extends A["_tag"]>(tag: Tag) => (u: unknown) => u is Extract<A, {
readonly _tag: Tag;
}>;
readonly $match: {
<Cases extends { readonly [Tag in A["_tag"]]: (args: Extract<A, {
readonly _tag: Tag;
}>) => any; }>(cases: Cases): (value: A) => Unify<ReturnType<Cases[A["_tag"]]>>;
<Cases extends { readonly [Tag in A["_tag"]]: (args: Extract<A, {
readonly _tag: Tag;
}>) => any; }>(value: A, cases: Cases): Unify<ReturnType<Cases[A["_tag"]]>>;
};
})[K]; } extends infer B ? B : never
The full constructors-and-matchers object type returned by
taggedEnum
.
When to use
Use when you want to annotate an exported constructor bundle so downstream
code keeps exact variant constructors and exhaustive matching.
Details
Includes:
- A constructor function for each variant (keyed by tag name)
$is(tag) — returns a type-guard that checks only the _tag field;
safe when the tag is globally unique and the value was produced by your
constructors. For untrusted input, validate with the Schema module first.
$match — exhaustive pattern matching (data-last or data-first)
Example (Using the constructor object)
import { Data } from "effect"
type Shape =
| { readonly _tag: "Circle"; readonly radius: number }
| { readonly _tag: "Rect"; readonly w: number; readonly h: number }
const { Circle, Rect, $is, $match } = Data.taggedEnum<Shape>()
const shape = Circle({ radius: 10 })
// Type guard
if ($is("Circle")(shape)) {
console.log(shape.radius)
}
// Pattern matching
const label = $match(shape, {
Circle: (s) => `circle r=${s.radius}`,
Rect: (s) => `rect ${s.w}x${s.h}`
})
Constructor<function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Constructor<A extends { readonly _tag: string; }>A extends { readonly _tag: string_tag: string }> = import TypesTypes.type Simplify<A> = {
[K in keyof A]: A[K]
} extends infer B
? B
: never
Flattens an intersection type into a single object type for readability.
When to use
Use to clean up IDE tooltips that show A & B & C instead of a merged
object.
Details
Does not change the type semantically, only its display.
Example (Simplifying an intersection)
import type { Types } from "effect"
// Without Simplify: IDE shows { a: number } & { b: string }
// With Simplify: IDE shows { a: number; b: string }
type Clean = Types.Simplify<{ a: number } & { b: string }>
Simplify<
{
readonly [function (type parameter) TagTag in function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Constructor<A extends { readonly _tag: string; }>A["_tag"]]: type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.ConstructorFrom<A, Tag extends keyof A = never> = (args: Types.VoidIfEmpty<{ readonly [P in keyof A as P extends Tag ? never : P]: A[P]; }>) => AFunction type that constructs a tagged-union variant from its fields,
excluding the keys listed in Tag.
When to use
Use to type an individual constructor for one tagged-union variant.
Details
The constructor returns the full variant type A. If no fields remain
after excluding Tag keys, the constructor argument type becomes void.
ConstructorFrom<
type Extract<T, U> = T extends U
? T
: never
Extract from T those types that are assignable to U
Extract<function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Constructor<A extends { readonly _tag: string; }>A, { readonly _tag: Tag extends A["_tag"]_tag: function (type parameter) TagTag }>,
"_tag"
>
} & {
readonly $is: <Tag extends A["_tag"]>(
tag: Tag
) => (u: unknown) => u is Extract<
A,
{
readonly _tag: Tag
}
>
$is: <function (type parameter) Tag in <Tag extends A["_tag"]>(tag: Tag): (u: unknown) => u is Extract<A, {
readonly _tag: Tag;
}>
Tag extends function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Constructor<A extends { readonly _tag: string; }>A["_tag"]>(
tag: Tag extends A["_tag"]tag: function (type parameter) Tag in <Tag extends A["_tag"]>(tag: Tag): (u: unknown) => u is Extract<A, {
readonly _tag: Tag;
}>
Tag
) => (u: unknownu: unknown) => u: unknownu is type Extract<T, U> = T extends U
? T
: never
Extract from T those types that are assignable to U
Extract<function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Constructor<A extends { readonly _tag: string; }>A, { readonly _tag: Tag extends A["_tag"]_tag: function (type parameter) Tag in <Tag extends A["_tag"]>(tag: Tag): (u: unknown) => u is Extract<A, {
readonly _tag: Tag;
}>
Tag }>
readonly $match: {
<
Cases extends {
readonly [Tag in A["_tag"]]: (
args: Extract<
A,
{
readonly _tag: Tag
}
>
) => any
}
>(
cases: Cases
): (
value: A
) => Unify<ReturnType<Cases[A["_tag"]]>>
<
Cases extends {
readonly [Tag in A["_tag"]]: (
args: Extract<
A,
{
readonly _tag: Tag
}
>
) => any
}
>(
value: A,
cases: Cases
): Unify<ReturnType<Cases[A["_tag"]]>>
}
$match: {
<
function (type parameter) Cases in <Cases extends { readonly [Tag in A["_tag"]]: (args: Extract<A, {
readonly _tag: Tag;
}>) => any; }>(cases: Cases): (value: A) => Unify<ReturnType<Cases[A["_tag"]]>>
Cases extends {
readonly [function (type parameter) TagTag in function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Constructor<A extends { readonly _tag: string; }>A["_tag"]]: (
args: Extract<
A,
{
readonly _tag: Tag
}
>
args: type Extract<T, U> = T extends U
? T
: never
Extract from T those types that are assignable to U
Extract<function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Constructor<A extends { readonly _tag: string; }>A, { readonly _tag: Tag extends A["_tag"]_tag: function (type parameter) TagTag }>
) => any
}
>(
cases: Cases extends { readonly [Tag in A["_tag"]]: (args: Extract<A, { readonly _tag: Tag; }>) => any; }cases: function (type parameter) Cases in <Cases extends { readonly [Tag in A["_tag"]]: (args: Extract<A, {
readonly _tag: Tag;
}>) => any; }>(cases: Cases): (value: A) => Unify<ReturnType<Cases[A["_tag"]]>>
Cases
): (value: A extends { readonly _tag: string; }value: function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Constructor<A extends { readonly _tag: string; }>A) => 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<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) Cases in <Cases extends { readonly [Tag in A["_tag"]]: (args: Extract<A, {
readonly _tag: Tag;
}>) => any; }>(cases: Cases): (value: A) => Unify<ReturnType<Cases[A["_tag"]]>>
Cases[function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Constructor<A extends { readonly _tag: string; }>A["_tag"]]>>
<
function (type parameter) Cases in <Cases extends { readonly [Tag in A["_tag"]]: (args: Extract<A, {
readonly _tag: Tag;
}>) => any; }>(value: A, cases: Cases): Unify<ReturnType<Cases[A["_tag"]]>>
Cases extends {
readonly [function (type parameter) TagTag in function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Constructor<A extends { readonly _tag: string; }>A["_tag"]]: (
args: Extract<
A,
{
readonly _tag: Tag
}
>
args: type Extract<T, U> = T extends U
? T
: never
Extract from T those types that are assignable to U
Extract<function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Constructor<A extends { readonly _tag: string; }>A, { readonly _tag: Tag extends A["_tag"]_tag: function (type parameter) TagTag }>
) => any
}
>(
value: A extends { readonly _tag: string; }value: function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Constructor<A extends { readonly _tag: string; }>A,
cases: Cases extends { readonly [Tag in A["_tag"]]: (args: Extract<A, { readonly _tag: Tag; }>) => any; }cases: function (type parameter) Cases in <Cases extends { readonly [Tag in A["_tag"]]: (args: Extract<A, {
readonly _tag: Tag;
}>) => any; }>(value: A, cases: Cases): Unify<ReturnType<Cases[A["_tag"]]>>
Cases
): 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<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) Cases in <Cases extends { readonly [Tag in A["_tag"]]: (args: Extract<A, {
readonly _tag: Tag;
}>) => any; }>(value: A, cases: Cases): Unify<ReturnType<Cases[A["_tag"]]>>
Cases[function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Constructor<A extends { readonly _tag: string; }>A["_tag"]]>>
}
}
>
/**
* Function type that constructs a tagged-union variant from its fields,
* excluding the keys listed in `Tag`.
*
* **When to use**
*
* Use to type an individual constructor for one tagged-union variant.
*
* **Details**
*
* The constructor returns the full variant type `A`. If no fields remain
* after excluding `Tag` keys, the constructor argument type becomes `void`.
*
* @category utility types
* @since 4.0.0
*/
export type type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.ConstructorFrom<A, Tag extends keyof A = never> = (args: Types.VoidIfEmpty<{ readonly [P in keyof A as P extends Tag ? never : P]: A[P]; }>) => AFunction type that constructs a tagged-union variant from its fields,
excluding the keys listed in Tag.
When to use
Use to type an individual constructor for one tagged-union variant.
Details
The constructor returns the full variant type A. If no fields remain
after excluding Tag keys, the constructor argument type becomes void.
ConstructorFrom<function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.ConstructorFrom<A, Tag extends keyof A = never>A, function (type parameter) Tag in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.ConstructorFrom<A, Tag extends keyof A = never>Tag extends keyof function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.ConstructorFrom<A, Tag extends keyof A = never>A = never> = (
args: Types.VoidIfEmpty<{
readonly [P in keyof A as P extends Tag
? never
: P]: A[P]
}>
args: import TypesTypes.type VoidIfEmpty<S> =
keyof S extends never ? void : S
Conditional type that returns void if S is an empty object type,
otherwise returns S.
When to use
Use to erase an empty object type from an API result or parameter position.
VoidIfEmpty<{ readonly [function (type parameter) PP in keyof function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.ConstructorFrom<A, Tag extends keyof A = never>A as function (type parameter) PP extends function (type parameter) Tag in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.ConstructorFrom<A, Tag extends keyof A = never>Tag ? never : function (type parameter) PP]: function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.ConstructorFrom<A, Tag extends keyof A = never>A[function (type parameter) PP] }>
) => function (type parameter) A in type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.ConstructorFrom<A, Tag extends keyof A = never>A
/**
* Type-guard and pattern-matching interface for generic tagged enums.
*
* **When to use**
*
* Use to type the `$is` and `$match` helpers for generic tagged enums.
*
* **Details**
*
* This is the `$is` / `$match` portion of the object returned by
* {@link taggedEnum} when used with a {@link WithGenerics} definition.
*
* @see {@link Constructor} — the non-generic equivalent
*
* @category models
* @since 3.2.0
*/
export interface interface TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.GenericMatchers<Z extends TaggedEnum.WithGenerics<number>>Type-guard and pattern-matching interface for generic tagged enums.
When to use
Use to type the $is and $match helpers for generic tagged enums.
Details
This is the $is / $match portion of the object returned by
taggedEnum
when used with a
WithGenerics
definition.
GenericMatchers<function (type parameter) Z in GenericMatchers<Z extends WithGenerics<number>>Z extends interface TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.WithGenerics<Count extends number>Defines a tagged enum shape that accepts generic type parameters.
When to use
Use when variant payloads need to be parameterized, such as Result<E, A>.
Details
Extend this interface and set taggedEnum to your union type, using
this["A"], this["B"], etc. as placeholders for the generics. The
Count parameter declares how many generics are used (up to 4).
Example (Defining a generic tagged enum)
import { Data } from "effect"
type MyResult<E, A> = Data.TaggedEnum<{
Failure: { readonly error: E }
Success: { readonly value: A }
}>
interface MyResultDef extends Data.TaggedEnum.WithGenerics<2> {
readonly taggedEnum: MyResult<this["A"], this["B"]>
}
const { Failure, Success } = Data.taggedEnum<MyResultDef>()
const ok = Success({ value: 42 })
// ok: { readonly _tag: "Success"; readonly value: number }
WithGenerics<number>> {
readonly TaggedEnum.GenericMatchers<Z extends TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.WithGenerics<number>>.$is: <Tag extends Z["taggedEnum"]["_tag"]>(tag: Tag) => {
<T extends TaggedEnum.Kind<Z, any, any, any, any>>(u: T): u is T & {
readonly _tag: Tag;
};
(u: unknown): u is Extract<TaggedEnum.Kind<Z>, {
readonly _tag: Tag;
}>;
}
$is: <function (type parameter) Tag in <Tag extends Z["taggedEnum"]["_tag"]>(tag: Tag): {
<T extends TaggedEnum.Kind<Z, any, any, any, any>>(u: T): u is T & {
readonly _tag: Tag;
};
(u: unknown): u is Extract<TaggedEnum.Kind<Z>, {
readonly _tag: Tag;
}>;
}
Tag extends function (type parameter) Z in GenericMatchers<Z extends WithGenerics<number>>Z["taggedEnum"]["_tag"]>(
tag: Tag extends Z["taggedEnum"]["_tag"]tag: function (type parameter) Tag in <Tag extends Z["taggedEnum"]["_tag"]>(tag: Tag): {
<T extends TaggedEnum.Kind<Z, any, any, any, any>>(u: T): u is T & {
readonly _tag: Tag;
};
(u: unknown): u is Extract<TaggedEnum.Kind<Z>, {
readonly _tag: Tag;
}>;
}
Tag
) => {
<function (type parameter) T in <T extends TaggedEnum.Kind<Z, any, any, any, any>>(u: T): u is T & {
readonly _tag: Tag;
}
T extends TaggedEnum.type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Kind<Z extends TaggedEnum.WithGenerics<number>, A = unknown, B = unknown, C = unknown, D = unknown> = (Z & {
readonly A: A;
readonly B: B;
readonly C: C;
readonly D: D;
})["taggedEnum"]
Applies concrete type arguments to a WithGenerics definition, producing
the resulting tagged union type.
When to use
Use to refer to a specific instantiation of a generic tagged enum in type signatures.
Example (Applying generics)
import type { Data } from "effect"
type Option<A> = Data.TaggedEnum<{
None: {}
Some: { readonly value: A }
}>
interface OptionDef extends Data.TaggedEnum.WithGenerics<1> {
readonly taggedEnum: Option<this["A"]>
}
// Resolve to the concrete union for `string`
type StringOption = Data.TaggedEnum.Kind<OptionDef, string>
// { _tag: "None" } | { _tag: "Some"; value: string }
Kind<function (type parameter) Z in GenericMatchers<Z extends WithGenerics<number>>Z, any, any, any, any>>(
u: T extends TaggedEnum.Kind<Z, any, any, any, any>u: function (type parameter) T in <T extends TaggedEnum.Kind<Z, any, any, any, any>>(u: T): u is T & {
readonly _tag: Tag;
}
T
): u: T extends TaggedEnum.Kind<Z, any, any, any, any>u is function (type parameter) T in <T extends TaggedEnum.Kind<Z, any, any, any, any>>(u: T): u is T & {
readonly _tag: Tag;
}
T & { readonly _tag: Tag extends Z["taggedEnum"]["_tag"]_tag: function (type parameter) Tag in <Tag extends Z["taggedEnum"]["_tag"]>(tag: Tag): {
<T extends TaggedEnum.Kind<Z, any, any, any, any>>(u: T): u is T & {
readonly _tag: Tag;
};
(u: unknown): u is Extract<TaggedEnum.Kind<Z>, {
readonly _tag: Tag;
}>;
}
Tag }
(u: unknownu: unknown): u: unknownu is type Extract<T, U> = T extends U
? T
: never
Extract from T those types that are assignable to U
Extract<TaggedEnum.type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Kind<Z extends TaggedEnum.WithGenerics<number>, A = unknown, B = unknown, C = unknown, D = unknown> = (Z & {
readonly A: A;
readonly B: B;
readonly C: C;
readonly D: D;
})["taggedEnum"]
Applies concrete type arguments to a WithGenerics definition, producing
the resulting tagged union type.
When to use
Use to refer to a specific instantiation of a generic tagged enum in type signatures.
Example (Applying generics)
import type { Data } from "effect"
type Option<A> = Data.TaggedEnum<{
None: {}
Some: { readonly value: A }
}>
interface OptionDef extends Data.TaggedEnum.WithGenerics<1> {
readonly taggedEnum: Option<this["A"]>
}
// Resolve to the concrete union for `string`
type StringOption = Data.TaggedEnum.Kind<OptionDef, string>
// { _tag: "None" } | { _tag: "Some"; value: string }
Kind<function (type parameter) Z in GenericMatchers<Z extends WithGenerics<number>>Z>, { readonly _tag: Tag extends Z["taggedEnum"]["_tag"]_tag: function (type parameter) Tag in <Tag extends Z["taggedEnum"]["_tag"]>(tag: Tag): {
<T extends TaggedEnum.Kind<Z, any, any, any, any>>(u: T): u is T & {
readonly _tag: Tag;
};
(u: unknown): u is Extract<TaggedEnum.Kind<Z>, {
readonly _tag: Tag;
}>;
}
Tag }>
}
readonly TaggedEnum.GenericMatchers<Z extends TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.WithGenerics<number>>.$match: { <A, B, C, D, Cases extends {
readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any;
}>(cases: Cases): (self: TaggedEnum.Kind<Z, A, B, C, D>) => Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>; <A, B, C, D, Cases extends {
readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any;
}>(self: TaggedEnum.Kind<Z, A, B, C, D>, cases: Cases): Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>> }
$match: {
<
function (type parameter) A in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(cases: Cases): (self: TaggedEnum.Kind<Z, A, B, C, D>) => Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
A,
function (type parameter) B in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(cases: Cases): (self: TaggedEnum.Kind<Z, A, B, C, D>) => Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
B,
function (type parameter) C in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(cases: Cases): (self: TaggedEnum.Kind<Z, A, B, C, D>) => Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
C,
function (type parameter) D in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(cases: Cases): (self: TaggedEnum.Kind<Z, A, B, C, D>) => Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
D,
function (type parameter) Cases in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(cases: Cases): (self: TaggedEnum.Kind<Z, A, B, C, D>) => Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
Cases extends {
readonly [function (type parameter) TagTag in function (type parameter) Z in GenericMatchers<Z extends WithGenerics<number>>Z["taggedEnum"]["_tag"]]: (
args: Extract<
Kind<Z, A, B, C, D>,
{
readonly _tag: Tag
}
>
args: type Extract<T, U> = T extends U
? T
: never
Extract from T those types that are assignable to U
Extract<
TaggedEnum.type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Kind<Z extends TaggedEnum.WithGenerics<number>, A = unknown, B = unknown, C = unknown, D = unknown> = (Z & {
readonly A: A;
readonly B: B;
readonly C: C;
readonly D: D;
})["taggedEnum"]
Applies concrete type arguments to a WithGenerics definition, producing
the resulting tagged union type.
When to use
Use to refer to a specific instantiation of a generic tagged enum in type signatures.
Example (Applying generics)
import type { Data } from "effect"
type Option<A> = Data.TaggedEnum<{
None: {}
Some: { readonly value: A }
}>
interface OptionDef extends Data.TaggedEnum.WithGenerics<1> {
readonly taggedEnum: Option<this["A"]>
}
// Resolve to the concrete union for `string`
type StringOption = Data.TaggedEnum.Kind<OptionDef, string>
// { _tag: "None" } | { _tag: "Some"; value: string }
Kind<function (type parameter) Z in GenericMatchers<Z extends WithGenerics<number>>Z, function (type parameter) A in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(cases: Cases): (self: TaggedEnum.Kind<Z, A, B, C, D>) => Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
A, function (type parameter) B in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(cases: Cases): (self: TaggedEnum.Kind<Z, A, B, C, D>) => Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
B, function (type parameter) C in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(cases: Cases): (self: TaggedEnum.Kind<Z, A, B, C, D>) => Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
C, function (type parameter) D in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(cases: Cases): (self: TaggedEnum.Kind<Z, A, B, C, D>) => Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
D>,
{ readonly _tag: Tag extends Z["taggedEnum"]["_tag"]_tag: function (type parameter) TagTag }
>
) => any
}
>(
cases: Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, { readonly _tag: Tag; }>) => any; }cases: function (type parameter) Cases in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(cases: Cases): (self: TaggedEnum.Kind<Z, A, B, C, D>) => Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
Cases
): (
self: Kind<Z, A, B, C, D>self: TaggedEnum.type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Kind<Z extends TaggedEnum.WithGenerics<number>, A = unknown, B = unknown, C = unknown, D = unknown> = (Z & {
readonly A: A;
readonly B: B;
readonly C: C;
readonly D: D;
})["taggedEnum"]
Applies concrete type arguments to a WithGenerics definition, producing
the resulting tagged union type.
When to use
Use to refer to a specific instantiation of a generic tagged enum in type signatures.
Example (Applying generics)
import type { Data } from "effect"
type Option<A> = Data.TaggedEnum<{
None: {}
Some: { readonly value: A }
}>
interface OptionDef extends Data.TaggedEnum.WithGenerics<1> {
readonly taggedEnum: Option<this["A"]>
}
// Resolve to the concrete union for `string`
type StringOption = Data.TaggedEnum.Kind<OptionDef, string>
// { _tag: "None" } | { _tag: "Some"; value: string }
Kind<function (type parameter) Z in GenericMatchers<Z extends WithGenerics<number>>Z, function (type parameter) A in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(cases: Cases): (self: TaggedEnum.Kind<Z, A, B, C, D>) => Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
A, function (type parameter) B in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(cases: Cases): (self: TaggedEnum.Kind<Z, A, B, C, D>) => Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
B, function (type parameter) C in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(cases: Cases): (self: TaggedEnum.Kind<Z, A, B, C, D>) => Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
C, function (type parameter) D in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(cases: Cases): (self: TaggedEnum.Kind<Z, A, B, C, D>) => Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
D>
) => 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<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) Cases in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(cases: Cases): (self: TaggedEnum.Kind<Z, A, B, C, D>) => Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
Cases[function (type parameter) Z in GenericMatchers<Z extends WithGenerics<number>>Z["taggedEnum"]["_tag"]]>>
<
function (type parameter) A in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(self: TaggedEnum.Kind<Z, A, B, C, D>, cases: Cases): Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
A,
function (type parameter) B in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(self: TaggedEnum.Kind<Z, A, B, C, D>, cases: Cases): Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
B,
function (type parameter) C in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(self: TaggedEnum.Kind<Z, A, B, C, D>, cases: Cases): Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
C,
function (type parameter) D in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(self: TaggedEnum.Kind<Z, A, B, C, D>, cases: Cases): Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
D,
function (type parameter) Cases in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(self: TaggedEnum.Kind<Z, A, B, C, D>, cases: Cases): Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
Cases extends {
readonly [function (type parameter) TagTag in function (type parameter) Z in GenericMatchers<Z extends WithGenerics<number>>Z["taggedEnum"]["_tag"]]: (
args: Extract<
Kind<Z, A, B, C, D>,
{
readonly _tag: Tag
}
>
args: type Extract<T, U> = T extends U
? T
: never
Extract from T those types that are assignable to U
Extract<
TaggedEnum.type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Kind<Z extends TaggedEnum.WithGenerics<number>, A = unknown, B = unknown, C = unknown, D = unknown> = (Z & {
readonly A: A;
readonly B: B;
readonly C: C;
readonly D: D;
})["taggedEnum"]
Applies concrete type arguments to a WithGenerics definition, producing
the resulting tagged union type.
When to use
Use to refer to a specific instantiation of a generic tagged enum in type signatures.
Example (Applying generics)
import type { Data } from "effect"
type Option<A> = Data.TaggedEnum<{
None: {}
Some: { readonly value: A }
}>
interface OptionDef extends Data.TaggedEnum.WithGenerics<1> {
readonly taggedEnum: Option<this["A"]>
}
// Resolve to the concrete union for `string`
type StringOption = Data.TaggedEnum.Kind<OptionDef, string>
// { _tag: "None" } | { _tag: "Some"; value: string }
Kind<function (type parameter) Z in GenericMatchers<Z extends WithGenerics<number>>Z, function (type parameter) A in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(self: TaggedEnum.Kind<Z, A, B, C, D>, cases: Cases): Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
A, function (type parameter) B in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(self: TaggedEnum.Kind<Z, A, B, C, D>, cases: Cases): Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
B, function (type parameter) C in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(self: TaggedEnum.Kind<Z, A, B, C, D>, cases: Cases): Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
C, function (type parameter) D in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(self: TaggedEnum.Kind<Z, A, B, C, D>, cases: Cases): Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
D>,
{ readonly _tag: Tag extends Z["taggedEnum"]["_tag"]_tag: function (type parameter) TagTag }
>
) => any
}
>(
self: Kind<Z, A, B, C, D>self: TaggedEnum.type TaggedEnum<A extends Record<string, Record<string, any>> & UntaggedChildren<A>>.Kind<Z extends TaggedEnum.WithGenerics<number>, A = unknown, B = unknown, C = unknown, D = unknown> = (Z & {
readonly A: A;
readonly B: B;
readonly C: C;
readonly D: D;
})["taggedEnum"]
Applies concrete type arguments to a WithGenerics definition, producing
the resulting tagged union type.
When to use
Use to refer to a specific instantiation of a generic tagged enum in type signatures.
Example (Applying generics)
import type { Data } from "effect"
type Option<A> = Data.TaggedEnum<{
None: {}
Some: { readonly value: A }
}>
interface OptionDef extends Data.TaggedEnum.WithGenerics<1> {
readonly taggedEnum: Option<this["A"]>
}
// Resolve to the concrete union for `string`
type StringOption = Data.TaggedEnum.Kind<OptionDef, string>
// { _tag: "None" } | { _tag: "Some"; value: string }
Kind<function (type parameter) Z in GenericMatchers<Z extends WithGenerics<number>>Z, function (type parameter) A in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(self: TaggedEnum.Kind<Z, A, B, C, D>, cases: Cases): Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
A, function (type parameter) B in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(self: TaggedEnum.Kind<Z, A, B, C, D>, cases: Cases): Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
B, function (type parameter) C in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(self: TaggedEnum.Kind<Z, A, B, C, D>, cases: Cases): Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
C, function (type parameter) D in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(self: TaggedEnum.Kind<Z, A, B, C, D>, cases: Cases): Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
D>,
cases: Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, { readonly _tag: Tag; }>) => any; }cases: function (type parameter) Cases in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(self: TaggedEnum.Kind<Z, A, B, C, D>, cases: Cases): Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
Cases
): 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<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) Cases in <A, B, C, D, Cases extends { readonly [Tag in Z["taggedEnum"]["_tag"]]: (args: Extract<TaggedEnum.Kind<Z, A, B, C, D>, {
readonly _tag: Tag;
}>) => any; }>(self: TaggedEnum.Kind<Z, A, B, C, D>, cases: Cases): Unify<ReturnType<Cases[Z["taggedEnum"]["_tag"]]>>
Cases[function (type parameter) Z in GenericMatchers<Z extends WithGenerics<number>>Z["taggedEnum"]["_tag"]]>>
}
}
}