Types
Provides compile-time utility types for TypeScript.
Everything in this module is type-level only; it does not define runtime values. The types are used throughout Effect to work with tuple lengths, object shapes, tagged unions, reason-tagged errors, mutability, exactness, required keys, concurrency settings, and variance markers.
Models
Concurrency type
Signature
type Concurrency = number | "unbounded";Other
Contravariant
Namespace for Contravariant-related utilities.
When to use
Use when referring to type-level helpers nested under Contravariant.
Namespace for Covariant-related utilities.
When to use
Use when referring to type-level helpers nested under Covariant.
Namespace for Invariant-related utilities.
When to use
Use when referring to type-level helpers nested under Invariant.
Utility Types
Contravariant type
Function-type alias encoding contravariant variance for a phantom type parameter.
When to use
Use as a phantom field type to make a type parameter contravariant in input position.
Details
Contravariant<A> is assignable to Contravariant<B> when B extends A, following the supertype direction.
See
Signature
type Contravariant<A> = (_: A) => void;Function-type alias encoding covariant variance for a phantom type parameter.
When to use
Use as a phantom field type to make a type parameter covariant in output position.
Details
Covariant<A> is assignable to Covariant<B> when A extends B, following the subtype direction.
See
Signature
type Covariant<A> = (_: never) => A;DeepMutable type
Recursively removes readonly from all properties, including nested objects, arrays, Map, and Set.
When to use
Use when you need a fully mutable version of a deeply readonly type.
Details
Recursion stops at primitives (string, number, boolean, bigint, symbol) and functions.
See
Signature
type DeepMutable<T> =
T extends ReadonlyMap<infer K, infer V>
? Map<DeepMutable<K>, DeepMutable<V>>
: T extends ReadonlySet<infer V>
? Set<DeepMutable<V>>
: T extends string | number | boolean | bigint | symbol | Function
? T
: { [K in keyof T]: DeepMutable<T[K]> };Determines if two types are exactly equal at the type level.
When to use
Use to assert type equality in conditional types or type-level tests.
Details
- Uses the <T>() => T extends X ? 1 : 2 trick for exact equality, distinguishing between any, unknown, never, and other types. - Resolves to true if X and Y are identical, false otherwise.
See
Signature
type Equals<X, Y> = <T>() => T extends X
? 1
: 2 extends <T>() => T extends Y ? 1 : 2
? true
: false;EqualsWith type
Determines if two types are equal, returning custom types for each case.
When to use
Use when you need a type-level if/else based on type equality.
Details
Returns Y when A and B are equal, N otherwise.
See
Signature
type EqualsWith<A, B, Y, N> = <T>() => T extends A
? 1
: 2 extends <T>() => T extends B ? 1 : 2
? Y
: N;ExcludeReason type
Excludes a specific reason variant by its _tag from an error's reason field.
When to use
Use when you need the remaining nested reason union type after removing variants handled by _tag, rather than the enclosing error type.
Details
Returns never if E has no reason field.
See
Signature
type ExcludeReason<E, K extends string> = E extends {
readonly reason: infer R;
}
? Exclude<
R,
{
readonly _tag: K;
}
>
: never;ExcludeTag type
Excludes members of a tagged union by their _tag value.
When to use
Use to remove tagged-union members whose _tag matches a specific value in type-level code.
Details
Non-tagged members of the union are preserved.
See
Signature
type ExcludeTag<E, K extends string> = Exclude<
E,
{
readonly _tag: K;
}
>;ExtractReason type
Extracts a specific reason variant by its _tag from an error's reason field.
When to use
Use when you need the nested reason variant type itself, selected by _tag, rather than the enclosing error type.
Details
Returns never if E has no matching reason variant.
See
Signature
type ExtractReason<E, K extends string> = E extends {
readonly reason: infer R;
}
? R extends {
readonly _tag: infer T;
}
? K extends T
? R
: never
: never
: never;ExtractTag type
Extracts a specific member of a tagged union by its _tag value.
When to use
Use to select tagged-union members whose _tag matches a specific value in type-level code.
Details
Returns never if no member matches the tag.
See
Signature
type ExtractTag<E, K extends string> = E extends {
readonly _tag: infer T;
}
? K extends T
? E
: never
: never;Checks whether an object type contains any of the specified keys.
When to use
Use to branch type-level logic when at least one key from a candidate key set exists on an object type.
Details
Returns true if at least one key from Key exists in A, false otherwise.
Signature
type Has<A, Key extends string> = Key extends infer K
? K extends keyof A
? true
: never
: never extends never
? false
: true;Function-type alias encoding invariant variance for a phantom type parameter.
When to use
Use as a phantom field type to make a type parameter invariant, neither covariant nor contravariant.
Details
A value of type Invariant<A> cannot be assigned to Invariant<B> unless A and B are the same type.
See
Signature
type Invariant<A> = (_: A) => A;Checks whether a type T is a union type.
When to use
Use to branch type-level logic depending on whether a type is a union.
Details
- Compares [T] against [UnionToIntersection<T>]. If they differ, T must be a union. - Returns true if T is a union of two or more members. - Returns false for single types, never, or any.
See
Signature
type IsUnion<T> = [T] extends [UnionToIntersection<T>] ? false : true;Left-biased merge of two object types where keys from Source take precedence over Target on conflict.
When to use
Use when you want left-biased merging where the first argument wins.
Details
Implemented as MergeRight<Target, Source>.
See
Signature
type MergeLeft<Source, Target> = MergeRight<Target, Source>;MergeRight type
Right-biased merge of two object types where keys from Source take precedence over Target on conflict.
When to use
Use when you want right-biased merging where the second argument wins.
Details
The result is automatically simplified via Simplify.
See
Signature
type MergeRight<Target, Source> = Simplify<Source & { [Key in keyof Target]: Target[Key] }>;Removes readonly from all properties of T. Supports arrays, tuples, and records.
When to use
Use when you need a mutable version of a readonly type.
Details
Only affects the top level; nested properties remain readonly.
See
Signature
type Mutable<T> = { [P in keyof T]: T[P] };NarrowReason type
Narrows a specific reason variant by its _tag from an error's reason field.
When to use
Use to preserve the original error shape while narrowing its nested reason field to the matching variant.
Details
Returns never if E has no matching reason variant.
See
Signature
type NarrowReason<E, K extends string> = E extends {
readonly reason: infer R;
}
? R extends {
readonly _tag: infer T;
}
? K extends T
? E & {
readonly reason: R;
}
: never
: never
: never;NoExcessProperties type
Constrains a type to prevent excess properties not present in T.
When to use
Use to catch accidental extra properties in generic functions at compile time.
Details
Extra keys from U that are not in T are mapped to never.
Signature
type NoExcessProperties<T, U> = T & Readonly<Record<Exclude<keyof U, keyof T>, never>>;Prevents TypeScript from inferring a type parameter from a specific position.
When to use
Use when a function parameter must match an inferred type without becoming an inference source.
Details
The parameter using NoInfer must still match the inferred type.
Signature
type NoInfer<A> = [A][A extends any ? 0 : never];NotFunction type
Excludes function types from a union, keeping only non-function members.
When to use
Use to filter out callable types from a union.
Details
Returns never if the entire union consists of function types.
Signature
type NotFunction<T> = T extends Function ? never : T;OmitReason type
Narrows an error's reason field to exclude a specific reason variant by its _tag.
When to use
Use to narrow the error to only the remaining reason variants after excluding the matched one.
Details
Returns never if E has no reason field or no remaining variants.
See
Signature
type OmitReason<E, K extends string> = E extends {
readonly reason: infer R;
}
? R extends {
readonly _tag: infer T;
}
? K extends T
? never
: E & {
readonly reason: R;
}
: never
: never;Extracts the reason type from an error that has a reason field.
When to use
Use when an error type stores nested sub-errors in a reason field and you need that field's full union type as a standalone type.
Details
Returns never if E has no reason field.
See
Signature
type ReasonOf<E> = E extends {
readonly reason: infer R;
}
? R
: never;ReasonTags type
Extracts the _tag values from the reason type of an error.
When to use
Use to get the discriminant values available inside a nested reason error union.
Details
This is shorthand for Tags<ReasonOf<E>>. It returns never if E has no reason field or the reason has no _tag.
See
Signature
type ReasonTags<E> = E extends {
readonly reason: {
readonly _tag: string;
};
}
? E["reason"]["_tag"]
: never;RequiredKeys type
Extracts the required keys from a type.
When to use
Use to derive the keys whose properties must be present on an object type.
Signature
type RequiredKeys<T> = { [K in keyof T]: {} extends Pick<T, K> ? never : K }[keyof T];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.
See
Signature
type Simplify<A> = { [K in keyof A]: A[K] } extends infer B ? B : never;Extracts the _tag string literal types from a union.
When to use
Use to get all discriminant values from a tagged union type.
Details
Members without a _tag field are ignored and produce never.
See
Signature
type Tags<E> = E extends {
readonly _tag: string;
}
? E["_tag"]
: never;Constructs a tuple type with exactly N elements of type T.
When to use
Use when you need a fixed-length array type, especially instead of manually writing [T, T, T, ...] for longer tuples.
Details
- If N is a literal number, produces a tuple of that exact length. - If N is the general number type (non-literal), degrades to Array<T>. - Negative numbers produce never.
See
Signature
type TupleOf<N extends number, T> = N extends N
? number extends N
? Array<T>
: TupleOf_<T, N, []>
: never;TupleOfAtLeast type
Constructs a tuple type with at least N elements of type T.
When to use
Use when you need a minimum-length array type that still allows additional elements. This is useful for variadic function signatures that require a minimum arity.
Details
Produces a tuple with N fixed positions followed by ...Array<T>.
See
Signature
type TupleOfAtLeast<N extends number, T> = [...TupleOf<N, T>, ...Array<T>];unassigned interface
Branded marker interface representing an unassigned type parameter.
When to use
Use when Effect's type-level machinery needs to represent a type parameter that has not been assigned yet.
Details
Used internally by the Effect type system to indicate that a type parameter has not been assigned a concrete type.
See
Signature
interface unassigned {
readonly _: typeof _;
}Branded marker interface representing an unhandled error type.
When to use
Use when Effect's type-level machinery needs to represent an error type that has not been handled yet.
Details
Used internally by the Effect type system to indicate that an error type has not been handled.
See
Signature
interface unhandled {
readonly _: typeof _;
}UnionToIntersection type
Transforms a union type into an intersection type.
When to use
Use to combine all members of a union into a single type with all their properties. This is useful in advanced generic code where you need to merge union variants.
Details
- Uses distributive conditional types and contra-variant inference. - If the union members are incompatible (e.g. string | number), the result is never.
See
Signature
type UnionToIntersection<T> = T extends any
? (x: T) => any
: never extends (x: infer R) => any
? R
: never;VoidIfEmpty type
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.
Signature
type VoidIfEmpty<S> = keyof S extends never ? void : S;
Describes the concurrency level for Effect operations that run multiple effects.
When to use
Use to type options that control how many effects may run at the same time.
Details
-
numberโ run at most N effects concurrently. -"unbounded"โ run all effects concurrently with no limit.