Data
Defines helpers for small immutable data models.
This module helps create plain classes, tagged classes, tagged unions, and
typed errors with readonly fields. Tagged values carry a _tag field, which
makes them easy to narrow with pattern matching or simple checks. These
helpers are commonly used for domain values and errors in Effect programs.
Constructors
Provides a base class for immutable data types.
When to use
Use when you need a lightweight immutable value type with .pipe() support.
Details
Extend Class with a type parameter to declare fields. The constructor
accepts those fields as a single object argument. When there are no fields
the argument is optional. Instances are Readonly and Pipeable.
See
- TaggedClass — adds a
_tagfield - Error — yieldable error variant
Signature
declare const Class: <A extends Record<string, any> = {}>(args: Types.VoidIfEmpty<{ [P in keyof A]: A[P] }>) => Readonly<A> & Pipeable.PipeableExample
(Defining a value class)
import { Data, Equal } from "effect"
class Person extends Data.Class<{ readonly name: string }> {}
Equal.equals(new Person({ name: "Mike" }), new Person({ name: "Mike" })) // => trueProvides a base class for yieldable errors.
When to use
Use when you need yieldable errors that do not need tag-based discrimination.
Details
Extends Cause.YieldableError, so instances can be yielded inside
Effect.gen to fail the enclosing effect. Fields are passed as a single
object; when there are no fields the argument is optional. If a message
field is provided, it becomes the error's .message.
See
- TaggedError — adds a
_tagforEffect.catchTag - Class — non-error data class
Signature
declare const Error: <A extends Record<string, any> = {}>(args: Types.VoidIfEmpty<{ [P in keyof A]: A[P] }>) => Cause.YieldableError & Readonly<A>Example
(Defining a yieldable error)
import { Data, Effect, Exit } from "effect"
class NetworkError extends Data.Error<{ readonly code: number readonly message: string}> {}
const program = Effect.gen(function*() { return yield* new NetworkError({ code: 500, message: "timeout" })})
Effect.runSync(Effect.exit(program)) // => Exit.fail(new NetworkError({ code: 500, message: "timeout" }))TaggedClass
Provides a base class for immutable data types with a _tag discriminator.
When to use
Use when you need a single-variant tagged type or an ad-hoc discriminator.
Details
Like Class, but the resulting instances also carry a
readonly _tag: Tag property. The _tag is excluded from the constructor
argument.
See
- Class — without a
_tag - TaggedError — tagged error variant
- TaggedEnum — multi-variant unions
Signature
declare function TaggedClass<Tag extends string>(tag: Tag): <A extends Record<string, any> = {}>(args: VoidIfEmpty<{ [P in string | number | symbol]: A[P] }>) => Readonly<A> & { readonly _tag: Tag;} & PipeableExample
(Defining a tagged class)
import { Data } from "effect"
class Person extends Data.TaggedClass("Person")<{ readonly name: string}> {}
new Person({ name: "Mike" })._tag // => "Person"taggedEnum
Creates constructors and matchers for a TaggedEnum type.
When to use
Use when you model a closed union with plain data objects and want construction, tag checks, and exhaustive matching from the same definition.
Details
Returns an object with:
- One constructor per variant (keyed by tag name)
$is(tag)— returns a type-guard function that checks only the_tagfield$match— exhaustive pattern matching (data-first or data-last)
Gotchas
- Constructors produce plain objects, not class instances.
$is(tag)only checks the_tagfield, not the full structure. It relies on the tag being globally unique and the value being produced by your constructors. For untrusted input, validate with theSchemamodule first.
See
- TaggedEnum — the type-level companion
- TaggedEnum.Constructor — the returned object type
- TaggedEnum.WithGenerics — generic enum support
Signature
declare const taggedEnum: { <Z extends WithGenerics<1>>(): Simplify<{ [Tag in string]: <A>(args: Args<Kind<Z, A, unknown, unknown, unknown>, Tag, Extract<Kind<Z, A, unknown, unknown, unknown>, { readonly _tag: Tag; }>>) => Extract<Kind<Z, A, unknown, unknown, unknown>, { readonly _tag: K; }> } & GenericMatchers<Z>>; <Z extends WithGenerics<2>>(): Simplify<{ [Tag in string]: <A, B>(args: Args<Kind<Z, A, B, unknown, unknown>, Tag, Extract<Kind<Z, A, B, unknown, unknown>, { readonly _tag: Tag; }>>) => Extract<Kind<Z, A, B, unknown, unknown>, { readonly _tag: K; }> } & GenericMatchers<Z>>; <Z extends WithGenerics<3>>(): Simplify<{ [Tag in string]: <A, B, C>(args: Args<Kind<Z, A, B, C, unknown>, Tag, Extract<Kind<Z, A, B, C, unknown>, { readonly _tag: Tag; }>>) => Extract<Kind<Z, A, B, C, unknown>, { readonly _tag: K; }> } & GenericMatchers<Z>>; <Z extends WithGenerics<4>>(): Simplify<{ [Tag in string]: <A, B, C, D>(args: Args<Kind<Z, A, B, C, D>, Tag, Extract<Kind<Z, A, B, C, D>, { readonly _tag: Tag; }>>) => Extract<Kind<Z, A, B, C, D>, { readonly _tag: K; }> } & GenericMatchers<Z>>; <A extends { readonly _tag: string; }>(): Simplify<{ [Tag in string]: 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 { [Tag in string]: (args: Extract<A, { readonly _tag: Tag; }>) => any }>(cases: Cases): (value: A) => Unify<ReturnType<Cases[A["_tag"]]>>; <Cases extends { [Tag in string]: (args: Extract<A, { readonly _tag: Tag; }>) => any }>(value: A, cases: Cases): Unify<ReturnType<Cases[A["_tag"]]>>; }; }>;}Example
(Creating and matching tagged enum values)
import { Data } from "effect"
type HttpError = Data.TaggedEnum<{ BadRequest: { readonly message: string } NotFound: { readonly url: string }}>
const { BadRequest, NotFound, $is, $match } = Data.taggedEnum<HttpError>()
const err = NotFound({ url: "/missing" })
$is("NotFound")(err) // => true
$match(err, { BadRequest: (e) => e.message, NotFound: (e) => `${e.url} not found`}) // => "/missing not found"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 }ok // => { value: 42, _tag: "Success" }TaggedError
Creates a tagged error class with a _tag discriminator.
When to use
Use when you need domain errors with discriminated-union handling.
Details
Like Error, but instances also carry a readonly _tag property,
enabling Effect.catchTag and Effect.catchTags for tag-based recovery.
The _tag is excluded from the constructor argument. Yielding an instance
inside Effect.gen fails the effect with this error.
See
- Error — without a
_tag - TaggedClass — tagged class that is not an error
Signature
declare const TaggedError: <Tag extends string>(tag: Tag) => <A extends Record<string, any> = {}>(args: Types.VoidIfEmpty<{ [P in keyof A]: A[P] }>) => Cause.YieldableError & { readonly _tag: Tag;} & Readonly<A>Example
(Recovering by tag)
import { Data, Effect } from "effect"
class NotFound extends Data.TaggedError("NotFound")<{ readonly resource: string}> {}
class Forbidden extends Data.TaggedError("Forbidden")<{ readonly reason: string}> {}
const program = Effect.gen(function*() { return yield* new NotFound({ resource: "/users/42" })})
const recovered = program.pipe( Effect.catchTag("NotFound", (e) => Effect.succeed(`missing: ${e.resource}`)))
await Effect.runPromise(recovered) // => "missing: /users/42"Models
TaggedEnum type
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.
See
- taggedEnum — constructors and matchers for a
TaggedEnum - TaggedEnum.WithGenerics — generic tagged enums
- TaggedEnum.Constructor — the constructor object type
Signature
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;} & { [K in keyof A[Tag]]: A[Tag][K] }> : never : neverExample
(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>()
BadRequest({ status: 400, message: "missing id" })._tag // => "BadRequest"Other
TaggedEnum
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)