Reference<Shape>Service key with a lazily computed default value.
Details
When a Reference is requested from a Context that does not contain an
override, Context getters that resolve references return the cached default
value instead of failing.
Example (Defining a reference with a default value)
import { Context } from "effect"
// Define a reference with a default value
const LoggerRef: Context.Reference<{ log: (msg: string) => void }> =
Context.Reference("Logger", {
defaultValue: () => ({ log: (msg: string) => console.log(msg) })
})
// The reference can be used without explicit provision
const context = Context.empty()
const logger = Context.get(context, LoggerRef) // Uses default valueexport interface interface Reference<in out Shape>Service key with a lazily computed default value.
Details
When a Reference is requested from a Context that does not contain an
override, Context getters that resolve references return the cached default
value instead of failing.
Example (Defining a reference with a default value)
import { Context } from "effect"
// Define a reference with a default value
const LoggerRef: Context.Reference<{ log: (msg: string) => void }> =
Context.Reference("Logger", {
defaultValue: () => ({ log: (msg: string) => console.log(msg) })
})
// The reference can be used without explicit provision
const context = Context.empty()
const logger = Context.get(context, LoggerRef) // Uses default value
Creates a context key with a default value.
When to use
Use when you need to define a context key with a lazily computed default
value.
Details
Context.Reference allows you to create a key that can hold a value. You
can provide a default value for the service, which will automatically be used
when the context is accessed, or override it with a custom implementation
when needed. The default value is computed lazily and cached on the
reference.
Example (Creating references with default values)
import { Context } from "effect"
// Create a reference with a default value
const LoggerRef = Context.Reference("Logger", {
defaultValue: () => ({ log: (msg: string) => console.log(msg) })
})
// The reference provides the default value when accessed from an empty context
const context = Context.empty()
const logger = Context.get(context, LoggerRef)
// You can also override the default value
const customContext = Context.make(LoggerRef, {
log: (msg: string) => `Custom: ${msg}`
})
const customLogger = Context.get(customContext, LoggerRef)
Reference<in out function (type parameter) Shape in Reference<in out Shape>Shape> extends interface Service<in out Identifier, in out Shape>Context key with helper methods for working with a service.
Details
context creates a one-service Context, use and useSync retrieve the
service from the current Effect context before applying a function, and of
is a type-level helper for service values.
Example (Defining a service key)
import { Context } from "effect"
// Define an identifier for a database service
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
// The key can be used to store and retrieve services
const context = Context.make(Database, { query: (sql) => `Result: ${sql}` })
Creates a Context service key.
When to use
Use when you need to define a context service key for a dependency that must
be provided by the surrounding context.
Details
Call Context.Service("Key") for a function-style key, or use the two-stage
form Context.Service<Self, Shape>()("Key") for class-style service
declarations. The returned key can be yielded as an Effect and passed to
Context.make, Context.add, and the Context getter functions.
Gotchas
The string key is the runtime identity of the service. Reusing the same key
string for unrelated services makes them occupy the same slot in a
Context.
Example (Creating service keys)
import { Context } from "effect"
// Create a simple service
const Database = Context.Service<{
query: (sql: string) => string
}>("Database")
// Create a service class
class Config extends Context.Service<Config, {
port: number
}>()("Config") {}
// Use the services to create contexts
const db = Context.make(Database, {
query: (sql) => `Result: ${sql}`
})
const config = Context.make(Config, { port: 8080 })
Namespace containing utility types for Context service keys.
Example (Extracting service types)
import { Context } from "effect"
const Database = Context.Service<{
query: (sql: string) => string
}>("Database")
// Extract service type from a key
type DatabaseService = Context.Service.Shape<typeof Database>
// Extract identifier type from a key
type DatabaseId = Context.Service.Identifier<typeof Database>
Service<never, function (type parameter) Shape in Reference<in out Shape>Shape> {
readonly [const ReferenceTypeId: "~effect/Context/Reference"ReferenceTypeId]: typeof const ReferenceTypeId: "~effect/Context/Reference"ReferenceTypeId
readonly Reference<in out Shape>.defaultValue: () => ShapedefaultValue: () => function (type parameter) Shape in Reference<in out Shape>Shape
[var Symbol: SymbolConstructorSymbol.SymbolConstructor.iterator: typeof Symbol.iteratorA method that returns the default iterator for an object. Called by the semantics of the
for-of statement.
iterator](): interface EffectIterator<T extends Effect<any, any, any>>Iterator interface for Effect generators, enabling Effect values to work with generator functions.
When to use
Use when defining or typing [Symbol.iterator]() for values typed as
Effects so yield* can pass their success type back into Effect.gen.
EffectIterator<interface Reference<in out Shape>Service key with a lazily computed default value.
Details
When a Reference is requested from a Context that does not contain an
override, Context getters that resolve references return the cached default
value instead of failing.
Example (Defining a reference with a default value)
import { Context } from "effect"
// Define a reference with a default value
const LoggerRef: Context.Reference<{ log: (msg: string) => void }> =
Context.Reference("Logger", {
defaultValue: () => ({ log: (msg: string) => console.log(msg) })
})
// The reference can be used without explicit provision
const context = Context.empty()
const logger = Context.get(context, LoggerRef) // Uses default value
Creates a context key with a default value.
When to use
Use when you need to define a context key with a lazily computed default
value.
Details
Context.Reference allows you to create a key that can hold a value. You
can provide a default value for the service, which will automatically be used
when the context is accessed, or override it with a custom implementation
when needed. The default value is computed lazily and cached on the
reference.
Example (Creating references with default values)
import { Context } from "effect"
// Create a reference with a default value
const LoggerRef = Context.Reference("Logger", {
defaultValue: () => ({ log: (msg: string) => console.log(msg) })
})
// The reference provides the default value when accessed from an empty context
const context = Context.empty()
const logger = Context.get(context, LoggerRef)
// You can also override the default value
const customContext = Context.make(LoggerRef, {
log: (msg: string) => `Custom: ${msg}`
})
const customLogger = Context.get(customContext, LoggerRef)
Reference<function (type parameter) Shape in Reference<in out Shape>Shape>>
new(_: never_: never): {}
}
/**
* Namespace containing utility types for `Context` service keys.
*
* **Example** (Extracting service types)
*
* ```ts
* import { Context } from "effect"
*
* const Database = Context.Service<{
* query: (sql: string) => string
* }>("Database")
*
* // Extract service type from a key
* type DatabaseService = Context.Service.Shape<typeof Database>
*
* // Extract identifier type from a key
* type DatabaseId = Context.Service.Identifier<typeof Database>
* ```
*
* @since 2.0.0
*/
export declare namespace Service {
/**
* Type that matches any `Context` service key regardless of its identifier or
* service shape.
*
* **Example** (Typing any service key)
*
* ```ts
* import { Context } from "effect"
*
* // Any represents any possible service type
* const services: Array<Context.Service.Any> = [
* Context.Service<{ log: (msg: string) => void }>("Logger"),
* Context.Service<{ query: (sql: string) => string }>("Database")
* ]
* ```
*
* @category models
* @since 4.0.0
*/
export type type Service<in out Identifier, in out Shape>.Any = Key<never, any> | Key<any, any>Type that matches any Context service key regardless of its identifier or
service shape.
Example (Typing any service key)
import { Context } from "effect"
// Any represents any possible service type
const services: Array<Context.Service.Any> = [
Context.Service<{ log: (msg: string) => void }>("Logger"),
Context.Service<{ query: (sql: string) => string }>("Database")
]
Any = interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<never, any> | interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<any, any>
/**
* Extracts the service implementation type stored behind a `Context` service
* key.
*
* **Example** (Extracting a service shape)
*
* ```ts
* import { Context } from "effect"
*
* const Database = Context.Service<{ query: (sql: string) => string }>(
* "Database"
* )
*
* // Extract the service shape from the service
* type DatabaseService = Context.Service.Shape<typeof Database>
* // DatabaseService is { query: (sql: string) => string }
* ```
*
* @category models
* @since 4.0.0
*/
export type type Service<in out Identifier, in out Shape>.Shape<T> = T extends Key<infer _I, infer S> ? S : neverExtracts the service implementation type stored behind a Context service
key.
Example (Extracting a service shape)
import { Context } from "effect"
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
// Extract the service shape from the service
type DatabaseService = Context.Service.Shape<typeof Database>
// DatabaseService is { query: (sql: string) => string }
Shape<function (type parameter) T in type Service<in out Identifier, in out Shape>.Shape<T>T> = function (type parameter) T in type Service<in out Identifier, in out Shape>.Shape<T>T extends interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<infer function (type parameter) _I_I, infer function (type parameter) SS> ? function (type parameter) SS : never
/**
* Extracts the identifier, or requirement type, associated with a `Context`
* service key.
*
* **Example** (Extracting a service identifier)
*
* ```ts
* import { Context } from "effect"
*
* const Database = Context.Service<{ query: (sql: string) => string }>(
* "Database"
* )
*
* // Extract the identifier type from a key
* type DatabaseId = Context.Service.Identifier<typeof Database>
* // DatabaseId is the identifier type
* ```
*
* @category models
* @since 2.0.0
*/
export type type Service<in out Identifier, in out Shape>.Identifier<T> = T extends Key<infer I, infer _S> ? I : neverExtracts the identifier, or requirement type, associated with a Context
service key.
Example (Extracting a service identifier)
import { Context } from "effect"
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
// Extract the identifier type from a key
type DatabaseId = Context.Service.Identifier<typeof Database>
// DatabaseId is the identifier type
Identifier<function (type parameter) T in type Service<in out Identifier, in out Shape>.Identifier<T>T> = function (type parameter) T in type Service<in out Identifier, in out Shape>.Identifier<T>T extends interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<infer function (type parameter) II, infer function (type parameter) _S_S> ? function (type parameter) II : never
}
const const TypeId: "~effect/Context"TypeId = "~effect/Context" as type const = "~effect/Context"const
/**
* Immutable collection of service implementations used for dependency
* injection in Effect programs.
*
* **Details**
*
* The type parameter tracks the service identifiers available in the context.
* At runtime, services are stored by each key's string `key`.
*
* **Example** (Creating a context with multiple services)
*
* ```ts
* import { Context } from "effect"
*
* // Create a context with multiple services
* const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
* const Database = Context.Service<{ query: (sql: string) => string }>(
* "Database"
* )
*
* const context = Context.make(Logger, {
* log: (msg: string) => console.log(msg)
* })
* .pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
* ```
*
* @category models
* @since 2.0.0
*/
export interface interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<in function (type parameter) Services in Context<in Services>Services> extends import EqualEqual.Equal, Pipeable, Inspectable {
readonly [const TypeId: "~effect/Context"TypeId]: {
readonly _Services: Types.Contravariant<Services>_Services: import TypesTypes.type Contravariant<A> = (_: A) => voidFunction-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.
Example (Defining a contravariant phantom type)
import type { Types } from "effect"
interface Consumer<T> {
readonly _phantom: Types.Contravariant<T>
readonly accept: (value: T) => void
}
Namespace for
Contravariant
-related utilities.
When to use
Use when referring to type-level helpers nested under Contravariant.
Contravariant<function (type parameter) Services in Context<in Services>Services>
}
readonly Context<in Services>.mapUnsafe: ReadonlyMap<string, any>mapUnsafe: interface ReadonlyMap<K, V>ReadonlyMap<string, any>
Context<in Services>.mutable: booleanmutable: boolean
}
/**
* Creates a `Context` from an existing service map.
*
* **When to use**
*
* Use when constructing a low-level `Context` from a trusted map whose lifecycle
* you control.
*
* **Gotchas**
*
* This is unsafe because later mutation of the provided map can affect the
* created `Context`. Prefer `empty`, `make`, `add`, or `merge` for normal
* Context construction.
*
* **Example** (Creating a context from a map)
*
* ```ts
* import { Context } from "effect"
*
* // Create a context from a Map (unsafe)
* const map = new Map([
* ["Logger", { log: (msg: string) => console.log(msg) }]
* ])
*
* const context = Context.makeUnsafe(map)
* ```
*
* @category constructors
* @since 4.0.0
*/
export const const makeUnsafe: <Services = never>(
mapUnsafe: ReadonlyMap<string, any>
) => Context<Services>
Creates a Context from an existing service map.
When to use
Use when constructing a low-level Context from a trusted map whose lifecycle
you control.
Gotchas
This is unsafe because later mutation of the provided map can affect the
created Context. Prefer empty, make, add, or merge for normal
Context construction.
Example (Creating a context from a map)
import { Context } from "effect"
// Create a context from a Map (unsafe)
const map = new Map([
["Logger", { log: (msg: string) => console.log(msg) }]
])
const context = Context.makeUnsafe(map)
makeUnsafe = <function (type parameter) Services in <Services = never>(mapUnsafe: ReadonlyMap<string, any>): Context<Services>Services = never>(mapUnsafe: ReadonlyMap<string, any>mapUnsafe: interface ReadonlyMap<K, V>ReadonlyMap<string, any>): interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services = never>(mapUnsafe: ReadonlyMap<string, any>): Context<Services>Services> => {
const const self: anyself = var Object: ObjectConstructorProvides functionality common to all JavaScript objects.
Object.ObjectConstructor.create(o: object | null): any (+1 overload)Creates an object that has the specified prototype or that has null prototype.
create(const Proto: Omit<
Context<never>,
"mapUnsafe" | "mutable"
>
Proto)
const self: anyself.mapUnsafe = mapUnsafe: ReadonlyMap<string, any>mapUnsafe
const self: anyself.mutable = false
return const self: anyself
}
const const Proto: Omit<
Context<never>,
"mapUnsafe" | "mutable"
>
Proto: type Omit<T, K extends keyof any> = {
[P in Exclude<keyof T, K>]: T[P]
}
Construct a type with the properties of T except for those in type K.
Omit<interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<never>, "mapUnsafe" | "mutable"> = {
...const PipeInspectableProto: {
pipe(): unknown;
toJSON(this: any): any;
toString(): string;
[NodeInspectSymbol](): any;
}
PipeInspectableProto,
[const TypeId: "~effect/Context"TypeId]: {
_Services: Types.Contravariant<never>_Services: (_: never_: never) => _: never_
},
function toJSON(this: Context<never>): { _id: string; services: Array<{ key: string; value: any }> }toJSON(this: Context<never>(parameter) this: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
this: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<never>) {
return {
_id: string_id: "Context",
services: {
key: string
value: any
}[]
services: var Array: ArrayConstructorArray.ArrayConstructor.from<[string, any]>(iterable: Iterable<[string, any]> | ArrayLike<[string, any]>): [string, any][] (+3 overloads)Creates an array from an iterable object.
from(this.Context<never>.mapUnsafe: ReadonlyMap<string, any>mapUnsafe).Array<[string, any]>.map<{
key: string;
value: any;
}>(callbackfn: (value: [string, any], index: number, array: [string, any][]) => {
key: string;
value: any;
}, thisArg?: any): {
key: string;
value: any;
}[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.
map(([key: stringkey, value: anyvalue]) => ({ key: stringkey, value: anyvalue }))
}
},
[import EqualEqual.const symbol: "~effect/interfaces/Equal"Defines the unique string identifier for the Equal interface.
When to use
Use when you implement custom equality and need the computed property key for
the equality method.
Details
This is a pure constant with no allocation or side effects.
Example (Implementing Equal on a class)
import { Equal, Hash } from "effect"
class UserId implements Equal.Equal {
constructor(readonly id: string) {}
[Equal.symbol](that: Equal.Equal): boolean {
return that instanceof UserId && this.id === that.id
}
[Hash.symbol](): number {
return Hash.string(this.id)
}
}
symbol]<function (type parameter) A in [Equal.symbol]<A>(this: Context<A>, that: unknown): booleanA>(this: Context<A>(parameter) this: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
this: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) A in [Equal.symbol]<A>(this: Context<A>, that: unknown): booleanA>, that: unknownthat: unknown): boolean {
if (
!const isContext: (
u: unknown
) => u is Context<never>
Checks whether the provided argument is a Context.
When to use
Use to narrow an unknown value before passing it to APIs that require a
Context.
Details
This checks the runtime Context marker and does not inspect which services
the context contains.
Gotchas
This guard only proves that the value is a Context; it does not prove that
any specific service is present.
Example (Checking for contexts)
import { Context } from "effect"
import * as assert from "node:assert"
assert.strictEqual(Context.isContext(Context.empty()), true)
isContext(that: unknownthat)
|| this.Context<in Services>.mapUnsafe: ReadonlyMap<string, any>mapUnsafe.ReadonlyMap<string, any>.size: numbersize !== that: Context<never>(parameter) that: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
that.Context<never>.mapUnsafe: ReadonlyMap<string, any>mapUnsafe.ReadonlyMap<string, any>.size: numbersize
) return false
for (const const k: stringk of this.Context<in Services>.mapUnsafe: ReadonlyMap<string, any>mapUnsafe.ReadonlyMap<string, any>.keys(): MapIterator<string>Returns an iterable of keys in the map
keys()) {
if (
!that: Context<never>(parameter) that: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
that.Context<never>.mapUnsafe: ReadonlyMap<string, any>mapUnsafe.ReadonlyMap<string, any>.has(key: string): booleanhas(const k: stringk) ||
!import EqualEqual.function equals<any, any>(self: any, that: any): boolean (+1 overload)Checks whether two values are deeply structurally equal.
When to use
Use when you need Effect's default structural equality check.
Details
Returns a boolean and never throws. Primitives are compared by value, and
NaN equals NaN. Objects implementing Equal delegate to their
[Equal.symbol] method; if only one operand implements Equal, the result
is false.
Dates compare by ISO string, RegExps compare by string representation,
arrays compare element-by-element, Maps and Sets compare entries
order-independently, and plain objects compare enumerable keys recursively.
Functions without an Equal implementation compare by reference. Circular
references are handled when both structures are circular at the same depth.
Hash values are checked first as a fast-path rejection. The function also
supports dual data-last usage: call it with one argument to get a curried
predicate.
Gotchas
- Results are cached per object pair in a WeakMap. Objects must not be
mutated after their first comparison.
- Map and Set comparisons are O(n²) in size.
Example (Comparing values)
import { Equal } from "effect"
// Primitives
console.log(Equal.equals(1, 1)) // true
console.log(Equal.equals(NaN, NaN)) // true
console.log(Equal.equals("a", "b")) // false
// Objects and arrays
console.log(Equal.equals({ a: 1, b: 2 }, { a: 1, b: 2 })) // true
console.log(Equal.equals([1, [2, 3]], [1, [2, 3]])) // true
// Dates
console.log(Equal.equals(new Date("2024-01-01"), new Date("2024-01-01"))) // true
// Maps (order-independent)
const m1 = new Map([["a", 1], ["b", 2]])
const m2 = new Map([["b", 2], ["a", 1]])
console.log(Equal.equals(m1, m2)) // true
// Curried form
const is5 = Equal.equals(5)
console.log(is5(5)) // true
console.log(is5(3)) // false
equals(this.Context<in Services>.mapUnsafe: ReadonlyMap<string, any>mapUnsafe.ReadonlyMap<string, any>.get(key: string): anyget(const k: stringk), that: Context<never>(parameter) that: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
that.Context<never>.mapUnsafe: ReadonlyMap<string, any>mapUnsafe.ReadonlyMap<string, any>.get(key: string): anyget(const k: stringk))
) {
return false
}
}
return true
},
[import HashHash.const symbol: "~effect/interfaces/Hash"Defines the unique identifier used to identify objects that implement the Hash interface.
When to use
Use as the computed property key for the method that supplies a custom hash
value on a Hash implementor.
symbol]<function (type parameter) A in [Hash.symbol]<A>(this: Context<A>): numberA>(this: Context<A>(parameter) this: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
this: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) A in [Hash.symbol]<A>(this: Context<A>): numberA>): number {
return import HashHash.const number: (n: number) => numberComputes a hash value for a number.
When to use
Use to hash a JavaScript number with Effect's numeric hash semantics.
Details
This function creates a hash value for numeric inputs, handling special cases
like NaN, Infinity, and -Infinity with distinct hash values. It uses bitwise operations to ensure good distribution
of hash values across different numeric inputs.
Example (Hashing numbers)
import { Hash } from "effect"
console.log(Hash.number(42)) // hash of 42
console.log(Hash.number(3.14)) // hash of 3.14
console.log(Hash.number(NaN)) // hash of "NaN"
console.log(Hash.number(Infinity)) // 0 (special case)
// Same numbers produce the same hash
console.log(Hash.number(100) === Hash.number(100)) // true
number(this.Context<in Services>.mapUnsafe: ReadonlyMap<string, any>mapUnsafe.ReadonlyMap<string, any>.size: numbersize)
}
}
/**
* Checks whether the provided argument is a `Context`.
*
* **When to use**
*
* Use to narrow an unknown value before passing it to APIs that require a
* `Context`.
*
* **Details**
*
* This checks the runtime `Context` marker and does not inspect which services
* the context contains.
*
* **Gotchas**
*
* This guard only proves that the value is a `Context`; it does not prove that
* any specific service is present.
*
* **Example** (Checking for contexts)
*
* ```ts
* import { Context } from "effect"
* import * as assert from "node:assert"
*
* assert.strictEqual(Context.isContext(Context.empty()), true)
* ```
*
* @see {@link isKey} for checking service keys
* @see {@link isReference} for checking references with defaults
*
* @category guards
* @since 2.0.0
*/
export const const isContext: (
u: unknown
) => u is Context<never>
Checks whether the provided argument is a Context.
When to use
Use to narrow an unknown value before passing it to APIs that require a
Context.
Details
This checks the runtime Context marker and does not inspect which services
the context contains.
Gotchas
This guard only proves that the value is a Context; it does not prove that
any specific service is present.
Example (Checking for contexts)
import { Context } from "effect"
import * as assert from "node:assert"
assert.strictEqual(Context.isContext(Context.empty()), true)
isContext = (u: unknownu: unknown): u: unknownu is interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<never> => hasProperty<"~effect/Context">(self: unknown, property: "~effect/Context"): self is { [K in "~effect/Context"]: unknown; } (+1 overload)Checks whether a value has a given property key.
When to use
Use when you need a Predicate guard for property access on unknown
values with a simple structural object check.
Details
Uses the in operator and isObjectKeyword. This does not check property
value types.
Example (Guarding object properties)
import { Predicate } from "effect"
const hasName = Predicate.hasProperty("name")
const data: unknown = { name: "Ada" }
if (hasName(data)) {
console.log(data.name)
}
hasProperty(u: unknownu, const TypeId: "~effect/Context"TypeId)
/**
* Checks whether the provided argument is a `Key`.
*
* **Example** (Checking for keys)
*
* ```ts
* import { Context } from "effect"
* import * as assert from "node:assert"
*
* assert.strictEqual(Context.isKey(Context.Service("Service")), true)
* ```
*
* @category guards
* @since 4.0.0
*/
export const const isKey: (
u: unknown
) => u is Key<any, any>
Checks whether the provided argument is a Key.
Example (Checking for keys)
import { Context } from "effect"
import * as assert from "node:assert"
assert.strictEqual(Context.isKey(Context.Service("Service")), true)
isKey = (u: unknownu: unknown): u: unknownu is interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<any, any> => hasProperty<"~effect/Context/Service">(self: unknown, property: "~effect/Context/Service"): self is { [K in "~effect/Context/Service"]: unknown; } (+1 overload)Checks whether a value has a given property key.
When to use
Use when you need a Predicate guard for property access on unknown
values with a simple structural object check.
Details
Uses the in operator and isObjectKeyword. This does not check property
value types.
Example (Guarding object properties)
import { Predicate } from "effect"
const hasName = Predicate.hasProperty("name")
const data: unknown = { name: "Ada" }
if (hasName(data)) {
console.log(data.name)
}
hasProperty(u: unknownu, const ServiceTypeId: ServiceTypeIdString literal type used as the runtime type identifier for Context
service keys.
Runtime type identifier attached to Context service keys and used by
isKey to recognize them.
ServiceTypeId)
/**
* Checks whether the provided argument is a `Reference`.
*
* **Example** (Checking for references)
*
* ```ts
* import { Context } from "effect"
* import * as assert from "node:assert"
*
* const LoggerRef = Context.Reference("Logger", {
* defaultValue: () => ({ log: (msg: string) => console.log(msg) })
* })
*
* assert.strictEqual(Context.isReference(LoggerRef), true)
* assert.strictEqual(Context.isReference(Context.Service("Key")), false)
* ```
*
* @category guards
* @since 3.11.0
*/
export const const isReference: (
u: unknown
) => u is Reference<any>
Checks whether the provided argument is a Reference.
Example (Checking for references)
import { Context } from "effect"
import * as assert from "node:assert"
const LoggerRef = Context.Reference("Logger", {
defaultValue: () => ({ log: (msg: string) => console.log(msg) })
})
assert.strictEqual(Context.isReference(LoggerRef), true)
assert.strictEqual(Context.isReference(Context.Service("Key")), false)
isReference = (u: unknownu: unknown): u: unknownu is interface Reference<in out Shape>Service key with a lazily computed default value.
Details
When a Reference is requested from a Context that does not contain an
override, Context getters that resolve references return the cached default
value instead of failing.
Example (Defining a reference with a default value)
import { Context } from "effect"
// Define a reference with a default value
const LoggerRef: Context.Reference<{ log: (msg: string) => void }> =
Context.Reference("Logger", {
defaultValue: () => ({ log: (msg: string) => console.log(msg) })
})
// The reference can be used without explicit provision
const context = Context.empty()
const logger = Context.get(context, LoggerRef) // Uses default value
Creates a context key with a default value.
When to use
Use when you need to define a context key with a lazily computed default
value.
Details
Context.Reference allows you to create a key that can hold a value. You
can provide a default value for the service, which will automatically be used
when the context is accessed, or override it with a custom implementation
when needed. The default value is computed lazily and cached on the
reference.
Example (Creating references with default values)
import { Context } from "effect"
// Create a reference with a default value
const LoggerRef = Context.Reference("Logger", {
defaultValue: () => ({ log: (msg: string) => console.log(msg) })
})
// The reference provides the default value when accessed from an empty context
const context = Context.empty()
const logger = Context.get(context, LoggerRef)
// You can also override the default value
const customContext = Context.make(LoggerRef, {
log: (msg: string) => `Custom: ${msg}`
})
const customLogger = Context.get(customContext, LoggerRef)
Reference<any> => hasProperty<"~effect/Context/Reference">(self: unknown, property: "~effect/Context/Reference"): self is { [K in "~effect/Context/Reference"]: unknown; } (+1 overload)Checks whether a value has a given property key.
When to use
Use when you need a Predicate guard for property access on unknown
values with a simple structural object check.
Details
Uses the in operator and isObjectKeyword. This does not check property
value types.
Example (Guarding object properties)
import { Predicate } from "effect"
const hasName = Predicate.hasProperty("name")
const data: unknown = { name: "Ada" }
if (hasName(data)) {
console.log(data.name)
}
hasProperty(u: unknownu, const ReferenceTypeId: "~effect/Context/Reference"ReferenceTypeId)
/**
* Returns an empty `Context`.
*
* **Example** (Creating an empty context)
*
* ```ts
* import { Context } from "effect"
* import * as assert from "node:assert"
*
* assert.strictEqual(Context.isContext(Context.empty()), true)
* ```
*
* @category constructors
* @since 2.0.0
*/
export const const empty: () => Context<never>Returns an empty Context.
Example (Creating an empty context)
import { Context } from "effect"
import * as assert from "node:assert"
assert.strictEqual(Context.isContext(Context.empty()), true)
empty = (): interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<never> => const emptyContext: Context<never>const emptyContext: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
emptyContext
const const emptyContext: Context<never>const emptyContext: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
emptyContext = const makeUnsafe: <Services = never>(
mapUnsafe: ReadonlyMap<string, any>
) => Context<Services>
Creates a Context from an existing service map.
When to use
Use when constructing a low-level Context from a trusted map whose lifecycle
you control.
Gotchas
This is unsafe because later mutation of the provided map can affect the
created Context. Prefer empty, make, add, or merge for normal
Context construction.
Example (Creating a context from a map)
import { Context } from "effect"
// Create a context from a Map (unsafe)
const map = new Map([
["Logger", { log: (msg: string) => console.log(msg) }]
])
const context = Context.makeUnsafe(map)
makeUnsafe(new var Map: MapConstructor
new () => Map<any, any> (+3 overloads)
Map())
/**
* Creates a new `Context` with a single service associated to the key.
*
* **Example** (Creating a context with one service)
*
* ```ts
* import { Context } from "effect"
* import * as assert from "node:assert"
*
* const Port = Context.Service<{ PORT: number }>("Port")
*
* const context = Context.make(Port, { PORT: 8080 })
*
* assert.deepStrictEqual(Context.get(context, Port), { PORT: 8080 })
* ```
*
* @category constructors
* @since 2.0.0
*/
export const const make: <I, S>(
key: Key<I, S>,
service: Types.NoInfer<S>
) => Context<I>
Creates a new Context with a single service associated to the key.
Example (Creating a context with one service)
import { Context } from "effect"
import * as assert from "node:assert"
const Port = Context.Service<{ PORT: number }>("Port")
const context = Context.make(Port, { PORT: 8080 })
assert.deepStrictEqual(Context.get(context, Port), { PORT: 8080 })
make = <function (type parameter) I in <I, S>(key: Key<I, S>, service: Types.NoInfer<S>): Context<I>I, function (type parameter) S in <I, S>(key: Key<I, S>, service: Types.NoInfer<S>): Context<I>S>(
key: Key<I, S>(parameter) key: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
key: interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<function (type parameter) I in <I, S>(key: Key<I, S>, service: Types.NoInfer<S>): Context<I>I, function (type parameter) S in <I, S>(key: Key<I, S>, service: Types.NoInfer<S>): Context<I>S>,
service: Types.NoInfer<S>service: import TypesTypes.type NoInfer<A> = [A][A extends any
? 0
: 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.
Example (Controlling inference)
import type { Types } from "effect"
declare function withDefault<T>(value: T, fallback: Types.NoInfer<T>): T
// T is inferred as "a" | "b" from the first argument only
const result = withDefault<"a" | "b">("a", "b")
NoInfer<function (type parameter) S in <I, S>(key: Key<I, S>, service: Types.NoInfer<S>): Context<I>S>
): interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) I in <I, S>(key: Key<I, S>, service: Types.NoInfer<S>): Context<I>I> => const makeUnsafe: <Services = never>(
mapUnsafe: ReadonlyMap<string, any>
) => Context<Services>
Creates a Context from an existing service map.
When to use
Use when constructing a low-level Context from a trusted map whose lifecycle
you control.
Gotchas
This is unsafe because later mutation of the provided map can affect the
created Context. Prefer empty, make, add, or merge for normal
Context construction.
Example (Creating a context from a map)
import { Context } from "effect"
// Create a context from a Map (unsafe)
const map = new Map([
["Logger", { log: (msg: string) => console.log(msg) }]
])
const context = Context.makeUnsafe(map)
makeUnsafe(new var Map: MapConstructor
new <string, Types.NoInfer<S>>(iterable?: Iterable<readonly [string, Types.NoInfer<S>]> | null | undefined) => Map<string, Types.NoInfer<S>> (+3 overloads)
Map([[key: Key<I, S>(parameter) key: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
key.Key<out Identifier, out Shape>.key: stringkey, service: Types.NoInfer<S>service]]))
/**
* Adds a service to a given `Context`.
*
* **When to use**
*
* Use when you need to store a known service value in a `Context`.
*
* **Details**
*
* If the context already contains the same service key, the new service
* replaces the previous one.
*
* **Example** (Adding a service to a context)
*
* ```ts
* import { Context, pipe } from "effect"
* import * as assert from "node:assert"
*
* const Port = Context.Service<{ PORT: number }>("Port")
* const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout")
*
* const someContext = Context.make(Port, { PORT: 8080 })
*
* const context = pipe(
* someContext,
* Context.add(Timeout, { TIMEOUT: 5000 })
* )
*
* assert.deepStrictEqual(Context.get(context, Port), { PORT: 8080 })
* assert.deepStrictEqual(Context.get(context, Timeout), { TIMEOUT: 5000 })
* ```
*
* @see {@link addOrOmit} for adding or removing a service from an `Option`
*
* @category adders
* @since 2.0.0
*/
export const const add: {
<I, S>(
key: Key<I, S>,
service: Types.NoInfer<S>
): <Services>(
self: Context<Services>
) => Context<Services | I>
<Services, I, S>(
self: Context<Services>,
key: Key<I, S>,
service: Types.NoInfer<S>
): Context<Services | I>
}
Adds a service to a given Context.
When to use
Use when you need to store a known service value in a Context.
Details
If the context already contains the same service key, the new service
replaces the previous one.
Example (Adding a service to a context)
import { Context, pipe } from "effect"
import * as assert from "node:assert"
const Port = Context.Service<{ PORT: number }>("Port")
const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout")
const someContext = Context.make(Port, { PORT: 8080 })
const context = pipe(
someContext,
Context.add(Timeout, { TIMEOUT: 5000 })
)
assert.deepStrictEqual(Context.get(context, Port), { PORT: 8080 })
assert.deepStrictEqual(Context.get(context, Timeout), { TIMEOUT: 5000 })
add: {
<function (type parameter) I in <I, S>(key: Key<I, S>, service: Types.NoInfer<S>): <Services>(self: Context<Services>) => Context<Services | I>I, function (type parameter) S in <I, S>(key: Key<I, S>, service: Types.NoInfer<S>): <Services>(self: Context<Services>) => Context<Services | I>S>(
key: Key<I, S>(parameter) key: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
key: interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<function (type parameter) I in <I, S>(key: Key<I, S>, service: Types.NoInfer<S>): <Services>(self: Context<Services>) => Context<Services | I>I, function (type parameter) S in <I, S>(key: Key<I, S>, service: Types.NoInfer<S>): <Services>(self: Context<Services>) => Context<Services | I>S>,
service: Types.NoInfer<S>service: import TypesTypes.type NoInfer<A> = [A][A extends any
? 0
: 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.
Example (Controlling inference)
import type { Types } from "effect"
declare function withDefault<T>(value: T, fallback: Types.NoInfer<T>): T
// T is inferred as "a" | "b" from the first argument only
const result = withDefault<"a" | "b">("a", "b")
NoInfer<function (type parameter) S in <I, S>(key: Key<I, S>, service: Types.NoInfer<S>): <Services>(self: Context<Services>) => Context<Services | I>S>
): <function (type parameter) Services in <Services>(self: Context<Services>): Context<Services | I>Services>(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services>(self: Context<Services>): Context<Services | I>Services>) => interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services>(self: Context<Services>): Context<Services | I>Services | function (type parameter) I in <I, S>(key: Key<I, S>, service: Types.NoInfer<S>): <Services>(self: Context<Services>) => Context<Services | I>I>
<function (type parameter) Services in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Types.NoInfer<S>): Context<Services | I>Services, function (type parameter) I in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Types.NoInfer<S>): Context<Services | I>I, function (type parameter) S in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Types.NoInfer<S>): Context<Services | I>S>(
self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Types.NoInfer<S>): Context<Services | I>Services>,
key: Key<I, S>(parameter) key: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
key: interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<function (type parameter) I in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Types.NoInfer<S>): Context<Services | I>I, function (type parameter) S in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Types.NoInfer<S>): Context<Services | I>S>,
service: Types.NoInfer<S>service: import TypesTypes.type NoInfer<A> = [A][A extends any
? 0
: 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.
Example (Controlling inference)
import type { Types } from "effect"
declare function withDefault<T>(value: T, fallback: Types.NoInfer<T>): T
// T is inferred as "a" | "b" from the first argument only
const result = withDefault<"a" | "b">("a", "b")
NoInfer<function (type parameter) S in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Types.NoInfer<S>): Context<Services | I>S>
): interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Types.NoInfer<S>): Context<Services | I>Services | function (type parameter) I in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Types.NoInfer<S>): Context<Services | I>I>
} = dual<(...args: Array<any>) => any, <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Types.NoInfer<S>) => Context<Services | I>>(arity: 3, body: <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Types.NoInfer<S>) => Context<Services | I>): ((...args: Array<any>) => any) & (<Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Types.NoInfer<S>) => Context<Services | I>) (+1 overload)Creates a function that can be called in data-first style or data-last
(pipe-friendly) style.
When to use
Use to expose one implementation through both direct and pipe-friendly
call styles.
Details
Pass either the arity of the uncurried function or a predicate that decides
whether the current call is data-first. Arity is the common case. Use a
predicate when optional arguments make arity ambiguous.
Example (Selecting data-first or data-last style by arity)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(2, (self, that) => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Defining overloads with call signatures)
import { Function, pipe } from "effect"
const sum: {
(that: number): (self: number) => number
(self: number, that: number): number
} = Function.dual(2, (self: number, that: number): number => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Selecting data-first or data-last style with a predicate)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(
(args) => args.length === 2,
(self, that) => self + that
)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
dual(3, <function (type parameter) Services in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Types.NoInfer<S>): Context<Services | I>Services, function (type parameter) I in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Types.NoInfer<S>): Context<Services | I>I, function (type parameter) S in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Types.NoInfer<S>): Context<Services | I>S>(
self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Types.NoInfer<S>): Context<Services | I>Services>,
key: Key<I, S>(parameter) key: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
key: interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<function (type parameter) I in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Types.NoInfer<S>): Context<Services | I>I, function (type parameter) S in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Types.NoInfer<S>): Context<Services | I>S>,
service: Types.NoInfer<S>service: import TypesTypes.type NoInfer<A> = [A][A extends any
? 0
: 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.
Example (Controlling inference)
import type { Types } from "effect"
declare function withDefault<T>(value: T, fallback: Types.NoInfer<T>): T
// T is inferred as "a" | "b" from the first argument only
const result = withDefault<"a" | "b">("a", "b")
NoInfer<function (type parameter) S in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Types.NoInfer<S>): Context<Services | I>S>
): interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Types.NoInfer<S>): Context<Services | I>Services | function (type parameter) I in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Types.NoInfer<S>): Context<Services | I>I> =>
const withMapUnsafe: <Services, B>(
self: Context<Services>,
f: (map: Map<string, any>) => void
) => Context<B>
withMapUnsafe(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self, (map: Map<string, any>map) => {
map: Map<string, any>map.Map<string, any>.set(key: string, value: any): Map<string, any>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(key: Key<I, S>(parameter) key: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
key.Key<out Identifier, out Shape>.key: stringkey, service: Types.NoInfer<S>service)
}))
/**
* Adds or removes a service depending on an `Option`.
*
* **When to use**
*
* Use when you need to add or omit a `Context` service based on an `Option`.
*
* **Details**
*
* When `service` is `Option.some`, the value is stored for the key. When it is
* `Option.none`, the key is removed from the returned `Context`.
*
* **Example** (Adding optional services)
*
* ```ts
* import { Context, Option } from "effect"
*
* const Port = Context.Service<{ PORT: number }>("Port")
*
* const withPort = Context.empty().pipe(
* Context.addOrOmit(Port, Option.some({ PORT: 8080 }))
* )
*
* const withoutPort = withPort.pipe(
* Context.addOrOmit(Port, Option.none())
* )
* ```
*
* @see {@link add} for always storing a service value
*
* @category adders
* @since 4.0.0
*/
export const const addOrOmit: {
<I, S>(
key: Key<I, S>,
service: Option.Option<Types.NoInfer<S>>
): <Services>(
self: Context<Services>
) => Context<Services | I>
<Services, I, S>(
self: Context<Services>,
key: Key<I, S>,
service: Option.Option<Types.NoInfer<S>>
): Context<Services | I>
}
Adds or removes a service depending on an Option.
When to use
Use when you need to add or omit a Context service based on an Option.
Details
When service is Option.some, the value is stored for the key. When it is
Option.none, the key is removed from the returned Context.
Example (Adding optional services)
import { Context, Option } from "effect"
const Port = Context.Service<{ PORT: number }>("Port")
const withPort = Context.empty().pipe(
Context.addOrOmit(Port, Option.some({ PORT: 8080 }))
)
const withoutPort = withPort.pipe(
Context.addOrOmit(Port, Option.none())
)
addOrOmit: {
<function (type parameter) I in <I, S>(key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>): <Services>(self: Context<Services>) => Context<Services | I>I, function (type parameter) S in <I, S>(key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>): <Services>(self: Context<Services>) => Context<Services | I>S>(
key: Key<I, S>(parameter) key: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
key: interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<function (type parameter) I in <I, S>(key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>): <Services>(self: Context<Services>) => Context<Services | I>I, function (type parameter) S in <I, S>(key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>): <Services>(self: Context<Services>) => Context<Services | I>S>,
service: Option.Option<Types.NoInfer<S>>service: import OptionOption.type Option<A> = Option.None<A> | Option.Some<A>The Option data type represents optional values. An Option<A> is either
Some<A>, containing a value of type A, or None, representing absence.
When to use
Use to represent initial values that may not yet exist
- Returning from partial functions (not defined for all inputs)
- Managing optional fields in data structures
Namespace containing utility types for Option.
When to use
Use to access type-level helpers associated with Option.
Option<import TypesTypes.type NoInfer<A> = [A][A extends any
? 0
: 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.
Example (Controlling inference)
import type { Types } from "effect"
declare function withDefault<T>(value: T, fallback: Types.NoInfer<T>): T
// T is inferred as "a" | "b" from the first argument only
const result = withDefault<"a" | "b">("a", "b")
NoInfer<function (type parameter) S in <I, S>(key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>): <Services>(self: Context<Services>) => Context<Services | I>S>>
): <function (type parameter) Services in <Services>(self: Context<Services>): Context<Services | I>Services>(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services>(self: Context<Services>): Context<Services | I>Services>) => interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services>(self: Context<Services>): Context<Services | I>Services | function (type parameter) I in <I, S>(key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>): <Services>(self: Context<Services>) => Context<Services | I>I>
<function (type parameter) Services in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>): Context<Services | I>Services, function (type parameter) I in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>): Context<Services | I>I, function (type parameter) S in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>): Context<Services | I>S>(
self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>): Context<Services | I>Services>,
key: Key<I, S>(parameter) key: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
key: interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<function (type parameter) I in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>): Context<Services | I>I, function (type parameter) S in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>): Context<Services | I>S>,
service: Option.Option<Types.NoInfer<S>>service: import OptionOption.type Option<A> = Option.None<A> | Option.Some<A>The Option data type represents optional values. An Option<A> is either
Some<A>, containing a value of type A, or None, representing absence.
When to use
Use to represent initial values that may not yet exist
- Returning from partial functions (not defined for all inputs)
- Managing optional fields in data structures
Namespace containing utility types for Option.
When to use
Use to access type-level helpers associated with Option.
Option<import TypesTypes.type NoInfer<A> = [A][A extends any
? 0
: 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.
Example (Controlling inference)
import type { Types } from "effect"
declare function withDefault<T>(value: T, fallback: Types.NoInfer<T>): T
// T is inferred as "a" | "b" from the first argument only
const result = withDefault<"a" | "b">("a", "b")
NoInfer<function (type parameter) S in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>): Context<Services | I>S>>
): interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>): Context<Services | I>Services | function (type parameter) I in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>): Context<Services | I>I>
} = dual<(...args: Array<any>) => any, <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>) => Context<Services | I>>(arity: 3, body: <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>) => Context<Services | I>): ((...args: Array<any>) => any) & (<Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>) => Context<Services | I>) (+1 overload)Creates a function that can be called in data-first style or data-last
(pipe-friendly) style.
When to use
Use to expose one implementation through both direct and pipe-friendly
call styles.
Details
Pass either the arity of the uncurried function or a predicate that decides
whether the current call is data-first. Arity is the common case. Use a
predicate when optional arguments make arity ambiguous.
Example (Selecting data-first or data-last style by arity)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(2, (self, that) => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Defining overloads with call signatures)
import { Function, pipe } from "effect"
const sum: {
(that: number): (self: number) => number
(self: number, that: number): number
} = Function.dual(2, (self: number, that: number): number => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Selecting data-first or data-last style with a predicate)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(
(args) => args.length === 2,
(self, that) => self + that
)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
dual(3, <function (type parameter) Services in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>): Context<Services | I>Services, function (type parameter) I in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>): Context<Services | I>I, function (type parameter) S in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>): Context<Services | I>S>(
self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>): Context<Services | I>Services>,
key: Key<I, S>(parameter) key: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
key: interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<function (type parameter) I in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>): Context<Services | I>I, function (type parameter) S in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>): Context<Services | I>S>,
service: Option.Option<Types.NoInfer<S>>service: import OptionOption.type Option<A> = Option.None<A> | Option.Some<A>The Option data type represents optional values. An Option<A> is either
Some<A>, containing a value of type A, or None, representing absence.
When to use
Use to represent initial values that may not yet exist
- Returning from partial functions (not defined for all inputs)
- Managing optional fields in data structures
Namespace containing utility types for Option.
When to use
Use to access type-level helpers associated with Option.
Option<import TypesTypes.type NoInfer<A> = [A][A extends any
? 0
: 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.
Example (Controlling inference)
import type { Types } from "effect"
declare function withDefault<T>(value: T, fallback: Types.NoInfer<T>): T
// T is inferred as "a" | "b" from the first argument only
const result = withDefault<"a" | "b">("a", "b")
NoInfer<function (type parameter) S in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>): Context<Services | I>S>>
): interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>): Context<Services | I>Services | function (type parameter) I in <Services, I, S>(self: Context<Services>, key: Key<I, S>, service: Option.Option<Types.NoInfer<S>>): Context<Services | I>I> =>
const withMapUnsafe: <Services, B>(
self: Context<Services>,
f: (map: Map<string, any>) => void
) => Context<B>
withMapUnsafe(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self, (map: Map<string, any>map) => {
if (service: Option.Option<Types.NoInfer<S>>service._tag: "None" | "Some"_tag === "None") {
map: Map<string, any>map.Map<string, any>.delete(key: string): booleandelete(key: Key<I, S>(parameter) key: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
key.Key<out Identifier, out Shape>.key: stringkey)
} else {
map: Map<string, any>map.Map<string, any>.set(key: string, value: any): Map<string, any>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(key: Key<I, S>(parameter) key: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
key.Key<out Identifier, out Shape>.key: stringkey, service: Option.Option<Types.NoInfer<S>>(parameter) service: {
_tag: "Some";
_op: "Some";
value: A;
valueOrUndefined: A;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
service.Some<NoInfer<S>>.value: Types.NoInfer<S>value)
}
}))
/**
* Gets the service for a key, or evaluates the fallback when a non-reference
* key is absent.
*
* **When to use**
*
* Use when you need a fallback for a missing `Context.Service` key while still
* resolving `Context.Reference` defaults.
*
* **Details**
*
* If the key is a `Context.Reference` and no override is stored in the
* context, its cached default value is returned instead of the fallback.
*
* **Gotchas**
*
* The fallback is not evaluated for missing `Context.Reference` keys because
* references resolve to their default value.
*
* **Example** (Falling back for missing services)
*
* ```ts
* import { Context } from "effect"
*
* const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
* const Database = Context.Service<{ query: (sql: string) => string }>(
* "Database"
* )
*
* const context = Context.make(Logger, {
* log: (msg: string) => console.log(msg)
* })
*
* const logger = Context.getOrElse(context, Logger, () => ({ log: () => {} }))
* const database = Context.getOrElse(
* context,
* Database,
* () => ({ query: () => "fallback" })
* )
*
* console.log(logger === Context.get(context, Logger)) // true
* console.log(database.query("SELECT 1")) // "fallback"
* ```
*
* @see {@link getOption} for returning `Option.none` when a non-reference key is missing
*
* @category getters
* @since 3.7.0
*/
export const const getOrElse: {
<S, I, B>(key: Key<I, S>, orElse: LazyArg<B>): <
Services
>(
self: Context<Services>
) => S | B
<Services, S, I, B>(
self: Context<Services>,
key: Key<I, S>,
orElse: LazyArg<B>
): S | B
}
Gets the service for a key, or evaluates the fallback when a non-reference
key is absent.
When to use
Use when you need a fallback for a missing Context.Service key while still
resolving Context.Reference defaults.
Details
If the key is a Context.Reference and no override is stored in the
context, its cached default value is returned instead of the fallback.
Gotchas
The fallback is not evaluated for missing Context.Reference keys because
references resolve to their default value.
Example (Falling back for missing services)
import { Context } from "effect"
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
const logger = Context.getOrElse(context, Logger, () => ({ log: () => {} }))
const database = Context.getOrElse(
context,
Database,
() => ({ query: () => "fallback" })
)
console.log(logger === Context.get(context, Logger)) // true
console.log(database.query("SELECT 1")) // "fallback"
getOrElse: {
<function (type parameter) S in <S, I, B>(key: Key<I, S>, orElse: LazyArg<B>): <Services>(self: Context<Services>) => S | BS, function (type parameter) I in <S, I, B>(key: Key<I, S>, orElse: LazyArg<B>): <Services>(self: Context<Services>) => S | BI, function (type parameter) B in <S, I, B>(key: Key<I, S>, orElse: LazyArg<B>): <Services>(self: Context<Services>) => S | BB>(key: Key<I, S>(parameter) key: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
key: interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<function (type parameter) I in <S, I, B>(key: Key<I, S>, orElse: LazyArg<B>): <Services>(self: Context<Services>) => S | BI, function (type parameter) S in <S, I, B>(key: Key<I, S>, orElse: LazyArg<B>): <Services>(self: Context<Services>) => S | BS>, orElse: LazyArg<B>orElse: type LazyArg<A> = () => AA zero-argument function that produces a value when invoked.
When to use
Use to type a lazy value provider that should not run until called.
Example (Creating a lazy argument)
import { Function } from "effect"
const constNull: Function.LazyArg<null> = Function.constant(null)
LazyArg<function (type parameter) B in <S, I, B>(key: Key<I, S>, orElse: LazyArg<B>): <Services>(self: Context<Services>) => S | BB>): <function (type parameter) Services in <Services>(self: Context<Services>): S | BServices>(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services>(self: Context<Services>): S | BServices>) => function (type parameter) S in <S, I, B>(key: Key<I, S>, orElse: LazyArg<B>): <Services>(self: Context<Services>) => S | BS | function (type parameter) B in <S, I, B>(key: Key<I, S>, orElse: LazyArg<B>): <Services>(self: Context<Services>) => S | BB
<function (type parameter) Services in <Services, S, I, B>(self: Context<Services>, key: Key<I, S>, orElse: LazyArg<B>): S | BServices, function (type parameter) S in <Services, S, I, B>(self: Context<Services>, key: Key<I, S>, orElse: LazyArg<B>): S | BS, function (type parameter) I in <Services, S, I, B>(self: Context<Services>, key: Key<I, S>, orElse: LazyArg<B>): S | BI, function (type parameter) B in <Services, S, I, B>(self: Context<Services>, key: Key<I, S>, orElse: LazyArg<B>): S | BB>(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, S, I, B>(self: Context<Services>, key: Key<I, S>, orElse: LazyArg<B>): S | BServices>, key: Key<I, S>(parameter) key: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
key: interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<function (type parameter) I in <Services, S, I, B>(self: Context<Services>, key: Key<I, S>, orElse: LazyArg<B>): S | BI, function (type parameter) S in <Services, S, I, B>(self: Context<Services>, key: Key<I, S>, orElse: LazyArg<B>): S | BS>, orElse: LazyArg<B>orElse: type LazyArg<A> = () => AA zero-argument function that produces a value when invoked.
When to use
Use to type a lazy value provider that should not run until called.
Example (Creating a lazy argument)
import { Function } from "effect"
const constNull: Function.LazyArg<null> = Function.constant(null)
LazyArg<function (type parameter) B in <Services, S, I, B>(self: Context<Services>, key: Key<I, S>, orElse: LazyArg<B>): S | BB>): function (type parameter) S in <Services, S, I, B>(self: Context<Services>, key: Key<I, S>, orElse: LazyArg<B>): S | BS | function (type parameter) B in <Services, S, I, B>(self: Context<Services>, key: Key<I, S>, orElse: LazyArg<B>): S | BB
} = dual<(...args: Array<any>) => any, <Services, S, I, B>(self: Context<Services>, key: Key<I, S>, orElse: LazyArg<B>) => S | B>(arity: 3, body: <Services, S, I, B>(self: Context<Services>, key: Key<I, S>, orElse: LazyArg<B>) => S | B): ((...args: Array<any>) => any) & (<Services, S, I, B>(self: Context<Services>, key: Key<I, S>, orElse: LazyArg<B>) => S | B) (+1 overload)Creates a function that can be called in data-first style or data-last
(pipe-friendly) style.
When to use
Use to expose one implementation through both direct and pipe-friendly
call styles.
Details
Pass either the arity of the uncurried function or a predicate that decides
whether the current call is data-first. Arity is the common case. Use a
predicate when optional arguments make arity ambiguous.
Example (Selecting data-first or data-last style by arity)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(2, (self, that) => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Defining overloads with call signatures)
import { Function, pipe } from "effect"
const sum: {
(that: number): (self: number) => number
(self: number, that: number): number
} = Function.dual(2, (self: number, that: number): number => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Selecting data-first or data-last style with a predicate)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(
(args) => args.length === 2,
(self, that) => self + that
)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
dual(3, <function (type parameter) Services in <Services, S, I, B>(self: Context<Services>, key: Key<I, S>, orElse: LazyArg<B>): S | BServices, function (type parameter) S in <Services, S, I, B>(self: Context<Services>, key: Key<I, S>, orElse: LazyArg<B>): S | BS, function (type parameter) I in <Services, S, I, B>(self: Context<Services>, key: Key<I, S>, orElse: LazyArg<B>): S | BI, function (type parameter) B in <Services, S, I, B>(self: Context<Services>, key: Key<I, S>, orElse: LazyArg<B>): S | BB>(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, S, I, B>(self: Context<Services>, key: Key<I, S>, orElse: LazyArg<B>): S | BServices>, key: Key<I, S>(parameter) key: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
key: interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<function (type parameter) I in <Services, S, I, B>(self: Context<Services>, key: Key<I, S>, orElse: LazyArg<B>): S | BI, function (type parameter) S in <Services, S, I, B>(self: Context<Services>, key: Key<I, S>, orElse: LazyArg<B>): S | BS>, orElse: LazyArg<B>orElse: type LazyArg<A> = () => AA zero-argument function that produces a value when invoked.
When to use
Use to type a lazy value provider that should not run until called.
Example (Creating a lazy argument)
import { Function } from "effect"
const constNull: Function.LazyArg<null> = Function.constant(null)
LazyArg<function (type parameter) B in <Services, S, I, B>(self: Context<Services>, key: Key<I, S>, orElse: LazyArg<B>): S | BB>): function (type parameter) S in <Services, S, I, B>(self: Context<Services>, key: Key<I, S>, orElse: LazyArg<B>): S | BS | function (type parameter) B in <Services, S, I, B>(self: Context<Services>, key: Key<I, S>, orElse: LazyArg<B>): S | BB => {
if (self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self.Context<in Services>.mapUnsafe: ReadonlyMap<string, any>mapUnsafe.ReadonlyMap<string, any>.has(key: string): booleanhas(key: Key<I, S>(parameter) key: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
key.Key<out Identifier, out Shape>.key: stringkey)) {
return self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self.Context<in Services>.mapUnsafe: ReadonlyMap<string, any>mapUnsafe.ReadonlyMap<string, any>.get(key: string): anyget(key: Key<I, S>(parameter) key: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
key.Key<out Identifier, out Shape>.key: stringkey)! as any
}
return const isReference: (
u: unknown
) => u is Reference<any>
Checks whether the provided argument is a Reference.
Example (Checking for references)
import { Context } from "effect"
import * as assert from "node:assert"
const LoggerRef = Context.Reference("Logger", {
defaultValue: () => ({ log: (msg: string) => console.log(msg) })
})
assert.strictEqual(Context.isReference(LoggerRef), true)
assert.strictEqual(Context.isReference(Context.Service("Key")), false)
isReference(key: Key<I, S>(parameter) key: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
key) ? const getDefaultValue: (
ref: Reference<any>
) => any
getDefaultValue(key: Key<I, S>(parameter) key: {
defaultValue: () => Shape;
of: (this: void, self: any) => any;
context: (self: any) => Context<never>;
use: (f: (service: any) => Effect<A, E, R>) => Effect<A, E, R>;
useSync: (f: (service: any) => A) => Effect<A, never, never>;
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
key) : orElse: LazyArg<B>orElse()
})
/**
* Returns the service currently stored for a key, or `undefined` when the key
* is absent.
*
* **When to use**
*
* Use when you need to read the service stored for a key without resolving
* `Context.Reference` defaults.
*
* **Gotchas**
*
* This is a raw lookup and does not resolve default values for
* `Context.Reference` keys.
*
* @see {@link getOption} for a reference-aware optional lookup
*
* @category getters
* @since 4.0.0
*/
export const const getOrUndefined: {
<S, I>(key: Key<I, S>): <Services>(
self: Context<Services>
) => S | undefined
<Services, S, I>(
self: Context<Services>,
key: Key<I, S>
): S | undefined
}
Returns the service currently stored for a key, or undefined when the key
is absent.
When to use
Use when you need to read the service stored for a key without resolving
Context.Reference defaults.
Gotchas
This is a raw lookup and does not resolve default values for
Context.Reference keys.
getOrUndefined: {
<function (type parameter) S in <S, I>(key: Key<I, S>): <Services>(self: Context<Services>) => S | undefinedS, function (type parameter) I in <S, I>(key: Key<I, S>): <Services>(self: Context<Services>) => S | undefinedI>(key: Key<I, S>(parameter) key: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
key: interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<function (type parameter) I in <S, I>(key: Key<I, S>): <Services>(self: Context<Services>) => S | undefinedI, function (type parameter) S in <S, I>(key: Key<I, S>): <Services>(self: Context<Services>) => S | undefinedS>): <function (type parameter) Services in <Services>(self: Context<Services>): S | undefinedServices>(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services>(self: Context<Services>): S | undefinedServices>) => function (type parameter) S in <S, I>(key: Key<I, S>): <Services>(self: Context<Services>) => S | undefinedS | undefined
<function (type parameter) Services in <Services, S, I>(self: Context<Services>, key: Key<I, S>): S | undefinedServices, function (type parameter) S in <Services, S, I>(self: Context<Services>, key: Key<I, S>): S | undefinedS, function (type parameter) I in <Services, S, I>(self: Context<Services>, key: Key<I, S>): S | undefinedI>(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, S, I>(self: Context<Services>, key: Key<I, S>): S | undefinedServices>, key: Key<I, S>(parameter) key: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
key: interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<function (type parameter) I in <Services, S, I>(self: Context<Services>, key: Key<I, S>): S | undefinedI, function (type parameter) S in <Services, S, I>(self: Context<Services>, key: Key<I, S>): S | undefinedS>): function (type parameter) S in <Services, S, I>(self: Context<Services>, key: Key<I, S>): S | undefinedS | undefined
} = dual<(...args: Array<any>) => any, <Services, S, I>(self: Context<Services>, key: Key<I, S>) => S | undefined>(arity: 2, body: <Services, S, I>(self: Context<Services>, key: Key<I, S>) => S | undefined): ((...args: Array<any>) => any) & (<Services, S, I>(self: Context<Services>, key: Key<I, S>) => S | undefined) (+1 overload)Creates a function that can be called in data-first style or data-last
(pipe-friendly) style.
When to use
Use to expose one implementation through both direct and pipe-friendly
call styles.
Details
Pass either the arity of the uncurried function or a predicate that decides
whether the current call is data-first. Arity is the common case. Use a
predicate when optional arguments make arity ambiguous.
Example (Selecting data-first or data-last style by arity)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(2, (self, that) => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Defining overloads with call signatures)
import { Function, pipe } from "effect"
const sum: {
(that: number): (self: number) => number
(self: number, that: number): number
} = Function.dual(2, (self: number, that: number): number => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Selecting data-first or data-last style with a predicate)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(
(args) => args.length === 2,
(self, that) => self + that
)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
dual(
2,
<function (type parameter) Services in <Services, S, I>(self: Context<Services>, key: Key<I, S>): S | undefinedServices, function (type parameter) S in <Services, S, I>(self: Context<Services>, key: Key<I, S>): S | undefinedS, function (type parameter) I in <Services, S, I>(self: Context<Services>, key: Key<I, S>): S | undefinedI>(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, S, I>(self: Context<Services>, key: Key<I, S>): S | undefinedServices>, key: Key<I, S>(parameter) key: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
key: interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<function (type parameter) I in <Services, S, I>(self: Context<Services>, key: Key<I, S>): S | undefinedI, function (type parameter) S in <Services, S, I>(self: Context<Services>, key: Key<I, S>): S | undefinedS>): function (type parameter) S in <Services, S, I>(self: Context<Services>, key: Key<I, S>): S | undefinedS | undefined => self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self.Context<in Services>.mapUnsafe: ReadonlyMap<string, any>mapUnsafe.ReadonlyMap<string, any>.get(key: string): anyget(key: Key<I, S>(parameter) key: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
key.Key<out Identifier, out Shape>.key: stringkey)
)
/**
* Gets the service for a key, throwing if an absent non-reference key cannot be
* resolved.
*
* **When to use**
*
* Use when you need to read a service from a context whose type does not prove
* the service is present.
*
* **Details**
*
* If the key is a `Context.Reference` and no override is stored in the
* context, its cached default value is returned. For absent non-reference keys,
* this function throws a runtime error.
*
* **Example** (Getting services unsafely)
*
* ```ts
* import { Context } from "effect"
* import * as assert from "node:assert"
*
* const Port = Context.Service<{ PORT: number }>("Port")
* const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout")
*
* const context = Context.make(Port, { PORT: 8080 })
*
* assert.deepStrictEqual(Context.getUnsafe(context, Port), { PORT: 8080 })
* assert.throws(() => Context.getUnsafe(context, Timeout))
* ```
*
* @see {@link get} for type-checked service access
* @see {@link getOption} for optional service access
*
* @category unsafe
* @since 4.0.0
*/
export const const getUnsafe: {
<S, I>(service: Key<I, S>): <Services>(
self: Context<Services>
) => S
<Services, S, I>(
self: Context<Services>,
services: Key<I, S>
): S
}
Gets the service for a key, throwing if an absent non-reference key cannot be
resolved.
When to use
Use when you need to read a service from a context whose type does not prove
the service is present.
Details
If the key is a Context.Reference and no override is stored in the
context, its cached default value is returned. For absent non-reference keys,
this function throws a runtime error.
Example (Getting services unsafely)
import { Context } from "effect"
import * as assert from "node:assert"
const Port = Context.Service<{ PORT: number }>("Port")
const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout")
const context = Context.make(Port, { PORT: 8080 })
assert.deepStrictEqual(Context.getUnsafe(context, Port), { PORT: 8080 })
assert.throws(() => Context.getUnsafe(context, Timeout))
getUnsafe: {
<function (type parameter) S in <S, I>(service: Key<I, S>): <Services>(self: Context<Services>) => SS, function (type parameter) I in <S, I>(service: Key<I, S>): <Services>(self: Context<Services>) => SI>(service: Key<I, S>(parameter) service: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
service: interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<function (type parameter) I in <S, I>(service: Key<I, S>): <Services>(self: Context<Services>) => SI, function (type parameter) S in <S, I>(service: Key<I, S>): <Services>(self: Context<Services>) => SS>): <function (type parameter) Services in <Services>(self: Context<Services>): SServices>(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services>(self: Context<Services>): SServices>) => function (type parameter) S in <S, I>(service: Key<I, S>): <Services>(self: Context<Services>) => SS
<function (type parameter) Services in <Services, S, I>(self: Context<Services>, services: Key<I, S>): SServices, function (type parameter) S in <Services, S, I>(self: Context<Services>, services: Key<I, S>): SS, function (type parameter) I in <Services, S, I>(self: Context<Services>, services: Key<I, S>): SI>(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, S, I>(self: Context<Services>, services: Key<I, S>): SServices>, services: Key<I, S>(parameter) services: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
services: interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<function (type parameter) I in <Services, S, I>(self: Context<Services>, services: Key<I, S>): SI, function (type parameter) S in <Services, S, I>(self: Context<Services>, services: Key<I, S>): SS>): function (type parameter) S in <Services, S, I>(self: Context<Services>, services: Key<I, S>): SS
} = dual<(...args: Array<any>) => any, <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>) => S>(arity: 2, body: <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>) => S): ((...args: Array<any>) => any) & (<Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>) => S) (+1 overload)Creates a function that can be called in data-first style or data-last
(pipe-friendly) style.
When to use
Use to expose one implementation through both direct and pipe-friendly
call styles.
Details
Pass either the arity of the uncurried function or a predicate that decides
whether the current call is data-first. Arity is the common case. Use a
predicate when optional arguments make arity ambiguous.
Example (Selecting data-first or data-last style by arity)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(2, (self, that) => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Defining overloads with call signatures)
import { Function, pipe } from "effect"
const sum: {
(that: number): (self: number) => number
(self: number, that: number): number
} = Function.dual(2, (self: number, that: number): number => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Selecting data-first or data-last style with a predicate)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(
(args) => args.length === 2,
(self, that) => self + that
)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
dual(
2,
<function (type parameter) Services in <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>): SServices, function (type parameter) I in <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>): SI extends function (type parameter) Services in <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>): SServices, function (type parameter) S in <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>): SS>(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>): SServices>, service: Key<I, S>(parameter) service: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
service: interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<function (type parameter) I in <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>): SI, function (type parameter) S in <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>): SS>): function (type parameter) S in <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>): SS => {
if (!self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self.Context<in Services>.mapUnsafe: ReadonlyMap<string, any>mapUnsafe.ReadonlyMap<string, any>.has(key: string): booleanhas(service: Key<I, S>(parameter) service: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
service.Key<out Identifier, out Shape>.key: stringkey)) {
if (const ReferenceTypeId: "~effect/Context/Reference"ReferenceTypeId in service: Key<I, S>(parameter) service: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
service) return const getDefaultValue: (
ref: Reference<any>
) => any
getDefaultValue(service: Key<I, S>service as any)
throw const serviceNotFoundError: (
service: Key<any, any>
) => Error
serviceNotFoundError(service: Key<I, S>(parameter) service: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
service)
}
return self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self.Context<in Services>.mapUnsafe: ReadonlyMap<string, any>mapUnsafe.ReadonlyMap<string, any>.get(key: string): anyget(service: Key<I, S>(parameter) service: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
service.Key<out Identifier, out Shape>.key: stringkey)! as any
}
)
/**
* Gets a service from the context that corresponds to the given key.
*
* **When to use**
*
* Use when you need type-checked access to a service already included in the
* context type.
*
* **Example** (Getting a service from a context)
*
* ```ts
* import { Context, pipe } from "effect"
* import * as assert from "node:assert"
*
* const Port = Context.Service<{ PORT: number }>("Port")
* const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout")
*
* const context = pipe(
* Context.make(Port, { PORT: 8080 }),
* Context.add(Timeout, { TIMEOUT: 5000 })
* )
*
* assert.deepStrictEqual(Context.get(context, Timeout), { TIMEOUT: 5000 })
* ```
*
* @see {@link getOption} for optional service access
* @see {@link getOrElse} for fallback values
*
* @category getters
* @since 2.0.0
*/
export const const get: {
<Services, I extends Services, S>(
service: Key<I, S>
): (self: Context<Services>) => S
<Services, I extends Services, S>(
self: Context<Services>,
service: Key<I, S>
): S
}
Gets a service from the context that corresponds to the given key.
When to use
Use when you need type-checked access to a service already included in the
context type.
Example (Getting a service from a context)
import { Context, pipe } from "effect"
import * as assert from "node:assert"
const Port = Context.Service<{ PORT: number }>("Port")
const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout")
const context = pipe(
Context.make(Port, { PORT: 8080 }),
Context.add(Timeout, { TIMEOUT: 5000 })
)
assert.deepStrictEqual(Context.get(context, Timeout), { TIMEOUT: 5000 })
get: {
<function (type parameter) Services in <Services, I extends Services, S>(service: Key<I, S>): (self: Context<Services>) => SServices, function (type parameter) I in <Services, I extends Services, S>(service: Key<I, S>): (self: Context<Services>) => SI extends function (type parameter) Services in <Services, I extends Services, S>(service: Key<I, S>): (self: Context<Services>) => SServices, function (type parameter) S in <Services, I extends Services, S>(service: Key<I, S>): (self: Context<Services>) => SS>(service: Key<I, S>(parameter) service: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
service: interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<function (type parameter) I in <Services, I extends Services, S>(service: Key<I, S>): (self: Context<Services>) => SI, function (type parameter) S in <Services, I extends Services, S>(service: Key<I, S>): (self: Context<Services>) => SS>): (self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, I extends Services, S>(service: Key<I, S>): (self: Context<Services>) => SServices>) => function (type parameter) S in <Services, I extends Services, S>(service: Key<I, S>): (self: Context<Services>) => SS
<function (type parameter) Services in <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>): SServices, function (type parameter) I in <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>): SI extends function (type parameter) Services in <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>): SServices, function (type parameter) S in <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>): SS>(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>): SServices>, service: Key<I, S>(parameter) service: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
service: interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<function (type parameter) I in <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>): SI, function (type parameter) S in <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>): SS>): function (type parameter) S in <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>): SS
} = const getUnsafe: {
<S, I>(service: Key<I, S>): <Services>(
self: Context<Services>
) => S
<Services, S, I>(
self: Context<Services>,
services: Key<I, S>
): S
}
Gets the service for a key, throwing if an absent non-reference key cannot be
resolved.
When to use
Use when you need to read a service from a context whose type does not prove
the service is present.
Details
If the key is a Context.Reference and no override is stored in the
context, its cached default value is returned. For absent non-reference keys,
this function throws a runtime error.
Example (Getting services unsafely)
import { Context } from "effect"
import * as assert from "node:assert"
const Port = Context.Service<{ PORT: number }>("Port")
const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout")
const context = Context.make(Port, { PORT: 8080 })
assert.deepStrictEqual(Context.getUnsafe(context, Port), { PORT: 8080 })
assert.throws(() => Context.getUnsafe(context, Timeout))
getUnsafe
/**
* Gets the value for a `Context.Reference`, returning its cached default when
* the context does not contain an override.
*
* **When to use**
*
* Use when you need a `Context.Reference` value resolved from either a stored
* override or the reference's default value.
*
* **Details**
*
* Stored overrides take precedence. If no override is present, the reference's
* default value is computed lazily and cached on the reference itself.
*
* **Gotchas**
*
* Mutable default values can be shared across contexts unless an override is
* provided, because the default is cached on the `Context.Reference`.
*
* **Example** (Getting reference defaults unsafely)
*
* ```ts
* import { Context } from "effect"
*
* const LoggerRef = Context.Reference("Logger", {
* defaultValue: () => ({ log: (msg: string) => console.log(msg) })
* })
*
* const context = Context.empty()
* const logger = Context.getReferenceUnsafe(context, LoggerRef)
*
* console.log(typeof logger.log) // "function"
* ```
*
* @see {@link getUnsafe} for unsafe access with any service key
* @see {@link get} for type-checked reference-aware access
* @see {@link getOption} for optional access to non-reference keys
*
* @category unsafe
* @since 4.0.0
*/
export const const getReferenceUnsafe: <Services, S>(
self: Context<Services>,
service: Reference<S>
) => S
Gets the value for a Context.Reference, returning its cached default when
the context does not contain an override.
When to use
Use when you need a Context.Reference value resolved from either a stored
override or the reference's default value.
Details
Stored overrides take precedence. If no override is present, the reference's
default value is computed lazily and cached on the reference itself.
Gotchas
Mutable default values can be shared across contexts unless an override is
provided, because the default is cached on the Context.Reference.
Example (Getting reference defaults unsafely)
import { Context } from "effect"
const LoggerRef = Context.Reference("Logger", {
defaultValue: () => ({ log: (msg: string) => console.log(msg) })
})
const context = Context.empty()
const logger = Context.getReferenceUnsafe(context, LoggerRef)
console.log(typeof logger.log) // "function"
getReferenceUnsafe = <function (type parameter) Services in <Services, S>(self: Context<Services>, service: Reference<S>): SServices, function (type parameter) S in <Services, S>(self: Context<Services>, service: Reference<S>): SS>(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, S>(self: Context<Services>, service: Reference<S>): SServices>, service: Reference<S>(parameter) service: {
defaultValue: () => Shape;
of: (this: void, self: S) => S;
context: (self: S) => Context<never>;
use: (f: (service: S) => Effect<A, E, R>) => Effect<A, E, R>;
useSync: (f: (service: S) => A) => Effect<A, never, never>;
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
service: interface Reference<in out Shape>Service key with a lazily computed default value.
Details
When a Reference is requested from a Context that does not contain an
override, Context getters that resolve references return the cached default
value instead of failing.
Example (Defining a reference with a default value)
import { Context } from "effect"
// Define a reference with a default value
const LoggerRef: Context.Reference<{ log: (msg: string) => void }> =
Context.Reference("Logger", {
defaultValue: () => ({ log: (msg: string) => console.log(msg) })
})
// The reference can be used without explicit provision
const context = Context.empty()
const logger = Context.get(context, LoggerRef) // Uses default value
Creates a context key with a default value.
When to use
Use when you need to define a context key with a lazily computed default
value.
Details
Context.Reference allows you to create a key that can hold a value. You
can provide a default value for the service, which will automatically be used
when the context is accessed, or override it with a custom implementation
when needed. The default value is computed lazily and cached on the
reference.
Example (Creating references with default values)
import { Context } from "effect"
// Create a reference with a default value
const LoggerRef = Context.Reference("Logger", {
defaultValue: () => ({ log: (msg: string) => console.log(msg) })
})
// The reference provides the default value when accessed from an empty context
const context = Context.empty()
const logger = Context.get(context, LoggerRef)
// You can also override the default value
const customContext = Context.make(LoggerRef, {
log: (msg: string) => `Custom: ${msg}`
})
const customLogger = Context.get(customContext, LoggerRef)
Reference<function (type parameter) S in <Services, S>(self: Context<Services>, service: Reference<S>): SS>): function (type parameter) S in <Services, S>(self: Context<Services>, service: Reference<S>): SS => {
if (!self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self.Context<in Services>.mapUnsafe: ReadonlyMap<string, any>mapUnsafe.ReadonlyMap<string, any>.has(key: string): booleanhas(service: Reference<S>(parameter) service: {
defaultValue: () => Shape;
of: (this: void, self: S) => S;
context: (self: S) => Context<never>;
use: (f: (service: S) => Effect<A, E, R>) => Effect<A, E, R>;
useSync: (f: (service: S) => A) => Effect<A, never, never>;
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
service.Key<out Identifier, out Shape>.key: stringkey)) {
return const getDefaultValue: (
ref: Reference<any>
) => any
getDefaultValue(service: Reference<S>(parameter) service: {
defaultValue: () => Shape;
of: (this: void, self: S) => S;
context: (self: S) => Context<never>;
use: (f: (service: S) => Effect<A, E, R>) => Effect<A, E, R>;
useSync: (f: (service: S) => A) => Effect<A, never, never>;
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
service as any)
}
return self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self.Context<in Services>.mapUnsafe: ReadonlyMap<string, any>mapUnsafe.ReadonlyMap<string, any>.get(key: string): anyget(service: Reference<S>(parameter) service: {
defaultValue: () => Shape;
of: (this: void, self: S) => S;
context: (self: S) => Context<never>;
use: (f: (service: S) => Effect<A, E, R>) => Effect<A, E, R>;
useSync: (f: (service: S) => A) => Effect<A, never, never>;
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
service.Key<out Identifier, out Shape>.key: stringkey)! as any
}
const const defaultValueCacheKey: "~effect/Context/defaultValue"defaultValueCacheKey = "~effect/Context/defaultValue" as type const = "~effect/Context/defaultValue"const
const const getDefaultValue: (
ref: Reference<any>
) => any
getDefaultValue = (ref: Reference<any>(parameter) ref: {
defaultValue: () => Shape;
of: (this: void, self: any) => any;
context: (self: any) => Context<never>;
use: (f: (service: any) => Effect<A, E, R>) => Effect<A, E, R>;
useSync: (f: (service: any) => A) => Effect<A, never, never>;
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
ref: interface Reference<in out Shape>Service key with a lazily computed default value.
Details
When a Reference is requested from a Context that does not contain an
override, Context getters that resolve references return the cached default
value instead of failing.
Example (Defining a reference with a default value)
import { Context } from "effect"
// Define a reference with a default value
const LoggerRef: Context.Reference<{ log: (msg: string) => void }> =
Context.Reference("Logger", {
defaultValue: () => ({ log: (msg: string) => console.log(msg) })
})
// The reference can be used without explicit provision
const context = Context.empty()
const logger = Context.get(context, LoggerRef) // Uses default value
Creates a context key with a default value.
When to use
Use when you need to define a context key with a lazily computed default
value.
Details
Context.Reference allows you to create a key that can hold a value. You
can provide a default value for the service, which will automatically be used
when the context is accessed, or override it with a custom implementation
when needed. The default value is computed lazily and cached on the
reference.
Example (Creating references with default values)
import { Context } from "effect"
// Create a reference with a default value
const LoggerRef = Context.Reference("Logger", {
defaultValue: () => ({ log: (msg: string) => console.log(msg) })
})
// The reference provides the default value when accessed from an empty context
const context = Context.empty()
const logger = Context.get(context, LoggerRef)
// You can also override the default value
const customContext = Context.make(LoggerRef, {
log: (msg: string) => `Custom: ${msg}`
})
const customLogger = Context.get(customContext, LoggerRef)
Reference<any>) => {
if (const defaultValueCacheKey: "~effect/Context/defaultValue"defaultValueCacheKey in ref: Reference<any>(parameter) ref: {
defaultValue: () => Shape;
of: (this: void, self: any) => any;
context: (self: any) => Context<never>;
use: (f: (service: any) => Effect<A, E, R>) => Effect<A, E, R>;
useSync: (f: (service: any) => A) => Effect<A, never, never>;
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
ref) {
return ref: Reference<any>ref[const defaultValueCacheKey: "~effect/Context/defaultValue"defaultValueCacheKey] as any
}
return (ref: Reference<any>(parameter) ref: {
defaultValue: () => Shape;
of: (this: void, self: any) => any;
context: (self: any) => Context<never>;
use: (f: (service: any) => Effect<A, E, R>) => Effect<A, E, R>;
useSync: (f: (service: any) => A) => Effect<A, never, never>;
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
ref as any)[const defaultValueCacheKey: "~effect/Context/defaultValue"defaultValueCacheKey] = ref: Reference<any>(parameter) ref: {
defaultValue: () => Shape;
of: (this: void, self: any) => any;
context: (self: any) => Context<never>;
use: (f: (service: any) => Effect<A, E, R>) => Effect<A, E, R>;
useSync: (f: (service: any) => A) => Effect<A, never, never>;
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
ref.Reference<any>.defaultValue: () => anydefaultValue()
}
const const serviceNotFoundError: (
service: Key<any, any>
) => Error
serviceNotFoundError = (service: Key<any, any>(parameter) service: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
service: interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<any, any>) => {
const const error: Errorconst error: {
name: string;
message: string;
stack: string;
cause: unknown;
}
error = new var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error(
`Service not found${service: Key<any, any>(parameter) service: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
service.Key<out Identifier, out Shape>.key: stringkey ? `: ${var String: StringConstructor
;(value?: any) => string
Allows manipulation and formatting of text strings and determination and location of substrings within strings.
String(service: Key<any, any>(parameter) service: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
service.Key<out Identifier, out Shape>.key: stringkey)}` : ""}`
)
if (service: Key<any, any>(parameter) service: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
service.Key<out Identifier, out Shape>.stack?: string | undefinedstack) {
const const lines: string[]lines = service: Key<any, any>(parameter) service: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
service.Key<out Identifier, out Shape>.stack?: stringstack.String.split(separator: string | RegExp, limit?: number): string[] (+1 overload)Split a string into substrings using the specified separator and return them as an array.
split("\n")
if (const lines: string[]lines.Array<T>.length: numberGets or sets the length of the array. This is a number one higher than the highest index in the array.
length > 2) {
const const afterAt: RegExpMatchArray | nullafterAt = const lines: string[]lines[2].String.match(matcher: {
[Symbol.match](string: string): RegExpMatchArray | null;
}): RegExpMatchArray | null (+1 overload)
Matches a string or an object that supports being matched against, and returns an array
containing the results of that search, or null if no matches are found.
match(/at (.*)/)
if (const afterAt: RegExpMatchArray | nullafterAt) {
const error: Errorconst error: {
name: string;
message: string;
stack: string;
cause: unknown;
}
error.Error.message: stringmessage = const error: Errorconst error: {
name: string;
message: string;
stack: string;
cause: unknown;
}
error.Error.message: stringmessage + ` (defined at ${const afterAt: RegExpMatchArrayafterAt[1]})`
}
}
}
if (const error: Errorconst error: {
name: string;
message: string;
stack: string;
cause: unknown;
}
error.Error.stack?: string | undefinedstack) {
const const lines: string[]lines = const error: Errorconst error: {
name: string;
message: string;
stack: string;
cause: unknown;
}
error.Error.stack?: stringstack.String.split(separator: string | RegExp, limit?: number): string[] (+1 overload)Split a string into substrings using the specified separator and return them as an array.
split("\n")
const lines: string[]lines.Array<string>.splice(start: number, deleteCount?: number): string[] (+1 overload)Removes elements from an array and, if necessary, inserts new elements in their place, returning the deleted elements.
splice(1, 3)
const error: Errorconst error: {
name: string;
message: string;
stack: string;
cause: unknown;
}
error.Error.stack?: string | undefinedstack = const lines: string[]lines.Array<string>.join(separator?: string): stringAdds all the elements of an array into a string, separated by the specified separator string.
join("\n")
}
return const error: Errorconst error: {
name: string;
message: string;
stack: string;
cause: unknown;
}
error
}
/**
* Gets the service for a key safely wrapped in an `Option`.
*
* **When to use**
*
* Use when you need to read a `Context` service as an `Option` so absence is
* represented as data.
*
* **Details**
*
* Returns `Option.some` when the service is stored in the context. If the key
* is a `Context.Reference` and no override is stored, returns `Option.some` of
* the cached default value. Missing non-reference keys return `Option.none`.
*
* **Example** (Getting optional services)
*
* ```ts
* import { Context, Option } from "effect"
* import * as assert from "node:assert"
*
* const Port = Context.Service<{ PORT: number }>("Port")
* const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout")
*
* const context = Context.make(Port, { PORT: 8080 })
*
* assert.deepStrictEqual(
* Context.getOption(context, Port),
* Option.some({ PORT: 8080 })
* )
* assert.deepStrictEqual(Context.getOption(context, Timeout), Option.none())
* ```
*
* @see {@link getOrElse} for returning a fallback value directly
*
* @category getters
* @since 2.0.0
*/
export const const getOption: {
<S, I>(service: Key<I, S>): <Services>(
self: Context<Services>
) => Option.Option<S>
<Services, S, I>(
self: Context<Services>,
service: Key<I, S>
): Option.Option<S>
}
Gets the service for a key safely wrapped in an Option.
When to use
Use when you need to read a Context service as an Option so absence is
represented as data.
Details
Returns Option.some when the service is stored in the context. If the key
is a Context.Reference and no override is stored, returns Option.some of
the cached default value. Missing non-reference keys return Option.none.
Example (Getting optional services)
import { Context, Option } from "effect"
import * as assert from "node:assert"
const Port = Context.Service<{ PORT: number }>("Port")
const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout")
const context = Context.make(Port, { PORT: 8080 })
assert.deepStrictEqual(
Context.getOption(context, Port),
Option.some({ PORT: 8080 })
)
assert.deepStrictEqual(Context.getOption(context, Timeout), Option.none())
getOption: {
<function (type parameter) S in <S, I>(service: Key<I, S>): <Services>(self: Context<Services>) => Option.Option<S>S, function (type parameter) I in <S, I>(service: Key<I, S>): <Services>(self: Context<Services>) => Option.Option<S>I>(service: Key<I, S>(parameter) service: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
service: interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<function (type parameter) I in <S, I>(service: Key<I, S>): <Services>(self: Context<Services>) => Option.Option<S>I, function (type parameter) S in <S, I>(service: Key<I, S>): <Services>(self: Context<Services>) => Option.Option<S>S>): <function (type parameter) Services in <Services>(self: Context<Services>): Option.Option<S>Services>(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services>(self: Context<Services>): Option.Option<S>Services>) => import OptionOption.type Option<A> = Option.None<A> | Option.Some<A>The Option data type represents optional values. An Option<A> is either
Some<A>, containing a value of type A, or None, representing absence.
When to use
Use to represent initial values that may not yet exist
- Returning from partial functions (not defined for all inputs)
- Managing optional fields in data structures
Namespace containing utility types for Option.
When to use
Use to access type-level helpers associated with Option.
Option<function (type parameter) S in <S, I>(service: Key<I, S>): <Services>(self: Context<Services>) => Option.Option<S>S>
<function (type parameter) Services in <Services, S, I>(self: Context<Services>, service: Key<I, S>): Option.Option<S>Services, function (type parameter) S in <Services, S, I>(self: Context<Services>, service: Key<I, S>): Option.Option<S>S, function (type parameter) I in <Services, S, I>(self: Context<Services>, service: Key<I, S>): Option.Option<S>I>(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, S, I>(self: Context<Services>, service: Key<I, S>): Option.Option<S>Services>, service: Key<I, S>(parameter) service: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
service: interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<function (type parameter) I in <Services, S, I>(self: Context<Services>, service: Key<I, S>): Option.Option<S>I, function (type parameter) S in <Services, S, I>(self: Context<Services>, service: Key<I, S>): Option.Option<S>S>): import OptionOption.type Option<A> = Option.None<A> | Option.Some<A>The Option data type represents optional values. An Option<A> is either
Some<A>, containing a value of type A, or None, representing absence.
When to use
Use to represent initial values that may not yet exist
- Returning from partial functions (not defined for all inputs)
- Managing optional fields in data structures
Namespace containing utility types for Option.
When to use
Use to access type-level helpers associated with Option.
Option<function (type parameter) S in <Services, S, I>(self: Context<Services>, service: Key<I, S>): Option.Option<S>S>
} = dual<(...args: Array<any>) => any, <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>) => Option.Option<S>>(arity: 2, body: <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>) => Option.Option<S>): ((...args: Array<any>) => any) & (<Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>) => Option.Option<S>) (+1 overload)Creates a function that can be called in data-first style or data-last
(pipe-friendly) style.
When to use
Use to expose one implementation through both direct and pipe-friendly
call styles.
Details
Pass either the arity of the uncurried function or a predicate that decides
whether the current call is data-first. Arity is the common case. Use a
predicate when optional arguments make arity ambiguous.
Example (Selecting data-first or data-last style by arity)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(2, (self, that) => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Defining overloads with call signatures)
import { Function, pipe } from "effect"
const sum: {
(that: number): (self: number) => number
(self: number, that: number): number
} = Function.dual(2, (self: number, that: number): number => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Selecting data-first or data-last style with a predicate)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(
(args) => args.length === 2,
(self, that) => self + that
)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
dual(2, <function (type parameter) Services in <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>): Option.Option<S>Services, function (type parameter) I in <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>): Option.Option<S>I extends function (type parameter) Services in <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>): Option.Option<S>Services, function (type parameter) S in <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>): Option.Option<S>S>(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>): Option.Option<S>Services>, service: Key<I, S>(parameter) service: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
service: interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<function (type parameter) I in <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>): Option.Option<S>I, function (type parameter) S in <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>): Option.Option<S>S>): import OptionOption.type Option<A> = Option.None<A> | Option.Some<A>The Option data type represents optional values. An Option<A> is either
Some<A>, containing a value of type A, or None, representing absence.
When to use
Use to represent initial values that may not yet exist
- Returning from partial functions (not defined for all inputs)
- Managing optional fields in data structures
Namespace containing utility types for Option.
When to use
Use to access type-level helpers associated with Option.
Option<function (type parameter) S in <Services, I extends Services, S>(self: Context<Services>, service: Key<I, S>): Option.Option<S>S> => {
if (self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self.Context<in Services>.mapUnsafe: ReadonlyMap<string, any>mapUnsafe.ReadonlyMap<string, any>.has(key: string): booleanhas(service: Key<I, S>(parameter) service: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
service.Key<out Identifier, out Shape>.key: stringkey)) {
return import OptionOption.const some: <A>(value: A) => Option<A>Wraps the given value into an Option to represent its presence.
When to use
Use to wrap a known present value as Option
- Returning a successful result from a partial function
Details
- Always returns
Some<A>
- Does not filter
null or undefined; use
fromNullishOr
for that
Example (Wrapping a value)
import { Option } from "effect"
// ┌─── Option<number>
// ▼
const value = Option.some(1)
console.log(value)
// Output: { _id: 'Option', _tag: 'Some', value: 1 }
some(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self.Context<in Services>.mapUnsafe: ReadonlyMap<string, any>mapUnsafe.ReadonlyMap<string, any>.get(key: string): anyget(service: Key<I, S>(parameter) service: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
service.Key<out Identifier, out Shape>.key: stringkey)! as any)
}
return const isReference: (
u: unknown
) => u is Reference<any>
Checks whether the provided argument is a Reference.
Example (Checking for references)
import { Context } from "effect"
import * as assert from "node:assert"
const LoggerRef = Context.Reference("Logger", {
defaultValue: () => ({ log: (msg: string) => console.log(msg) })
})
assert.strictEqual(Context.isReference(LoggerRef), true)
assert.strictEqual(Context.isReference(Context.Service("Key")), false)
isReference(service: Key<I, S>(parameter) service: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
service) ? import OptionOption.const some: <A>(value: A) => Option<A>Wraps the given value into an Option to represent its presence.
When to use
Use to wrap a known present value as Option
- Returning a successful result from a partial function
Details
- Always returns
Some<A>
- Does not filter
null or undefined; use
fromNullishOr
for that
Example (Wrapping a value)
import { Option } from "effect"
// ┌─── Option<number>
// ▼
const value = Option.some(1)
console.log(value)
// Output: { _id: 'Option', _tag: 'Some', value: 1 }
some(const getDefaultValue: (
ref: Reference<any>
) => any
getDefaultValue(service: Key<I, S>(parameter) service: {
defaultValue: () => Shape;
of: (this: void, self: any) => any;
context: (self: any) => Context<never>;
use: (f: (service: any) => Effect<A, E, R>) => Effect<A, E, R>;
useSync: (f: (service: any) => A) => Effect<A, never, never>;
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
service as any)) : import OptionOption.const none: <A = never>() => Option<A>Creates an Option representing the absence of a value.
When to use
Use to represent a missing or uninitialized value, such as returning "no
result" from a function.
Details
- Returns
Option<never>, which is a subtype of Option<A> for any A
- Always returns the same singleton instance
Example (Creating an empty Option)
import { Option } from "effect"
// ┌─── Option<never>
// ▼
const noValue = Option.none()
console.log(noValue)
// Output: { _id: 'Option', _tag: 'None' }
none()
})
/**
* Merges two `Context`s into one.
*
* **When to use**
*
* Use when you need to combine two contexts.
*
* **Details**
*
* When both contexts contain the same service key, the service from `that`
* overrides the service from `self`.
*
* **Example** (Merging two contexts)
*
* ```ts
* import { Context } from "effect"
* import * as assert from "node:assert"
*
* const Port = Context.Service<{ PORT: number }>("Port")
* const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout")
*
* const firstContext = Context.make(Port, { PORT: 8080 })
* const secondContext = Context.make(Timeout, { TIMEOUT: 5000 })
*
* const context = Context.merge(firstContext, secondContext)
*
* assert.deepStrictEqual(Context.get(context, Port), { PORT: 8080 })
* assert.deepStrictEqual(Context.get(context, Timeout), { TIMEOUT: 5000 })
* ```
*
* @see {@link mergeAll} for merging more than two contexts at once
*
* @category combining
* @since 2.0.0
*/
export const const merge: {
<R1>(that: Context<R1>): <Services>(
self: Context<Services>
) => Context<R1 | Services>
<Services, R1>(
self: Context<Services>,
that: Context<R1>
): Context<Services | R1>
}
Merges two Contexts into one.
When to use
Use when you need to combine two contexts.
Details
When both contexts contain the same service key, the service from that
overrides the service from self.
Example (Merging two contexts)
import { Context } from "effect"
import * as assert from "node:assert"
const Port = Context.Service<{ PORT: number }>("Port")
const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout")
const firstContext = Context.make(Port, { PORT: 8080 })
const secondContext = Context.make(Timeout, { TIMEOUT: 5000 })
const context = Context.merge(firstContext, secondContext)
assert.deepStrictEqual(Context.get(context, Port), { PORT: 8080 })
assert.deepStrictEqual(Context.get(context, Timeout), { TIMEOUT: 5000 })
merge: {
<function (type parameter) R1 in <R1>(that: Context<R1>): <Services>(self: Context<Services>) => Context<R1 | Services>R1>(that: Context<R1>(parameter) that: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
that: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) R1 in <R1>(that: Context<R1>): <Services>(self: Context<Services>) => Context<R1 | Services>R1>): <function (type parameter) Services in <Services>(self: Context<Services>): Context<R1 | Services>Services>(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services>(self: Context<Services>): Context<R1 | Services>Services>) => interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) R1 in <R1>(that: Context<R1>): <Services>(self: Context<Services>) => Context<R1 | Services>R1 | function (type parameter) Services in <Services>(self: Context<Services>): Context<R1 | Services>Services>
<function (type parameter) Services in <Services, R1>(self: Context<Services>, that: Context<R1>): Context<Services | R1>Services, function (type parameter) R1 in <Services, R1>(self: Context<Services>, that: Context<R1>): Context<Services | R1>R1>(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, R1>(self: Context<Services>, that: Context<R1>): Context<Services | R1>Services>, that: Context<R1>(parameter) that: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
that: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) R1 in <Services, R1>(self: Context<Services>, that: Context<R1>): Context<Services | R1>R1>): interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, R1>(self: Context<Services>, that: Context<R1>): Context<Services | R1>Services | function (type parameter) R1 in <Services, R1>(self: Context<Services>, that: Context<R1>): Context<Services | R1>R1>
} = dual<(...args: Array<any>) => any, <Services, R1>(self: Context<Services>, that: Context<R1>) => Context<Services | R1>>(arity: 2, body: <Services, R1>(self: Context<Services>, that: Context<R1>) => Context<Services | R1>): ((...args: Array<any>) => any) & (<Services, R1>(self: Context<Services>, that: Context<R1>) => Context<Services | R1>) (+1 overload)Creates a function that can be called in data-first style or data-last
(pipe-friendly) style.
When to use
Use to expose one implementation through both direct and pipe-friendly
call styles.
Details
Pass either the arity of the uncurried function or a predicate that decides
whether the current call is data-first. Arity is the common case. Use a
predicate when optional arguments make arity ambiguous.
Example (Selecting data-first or data-last style by arity)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(2, (self, that) => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Defining overloads with call signatures)
import { Function, pipe } from "effect"
const sum: {
(that: number): (self: number) => number
(self: number, that: number): number
} = Function.dual(2, (self: number, that: number): number => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Selecting data-first or data-last style with a predicate)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(
(args) => args.length === 2,
(self, that) => self + that
)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
dual(2, <function (type parameter) Services in <Services, R1>(self: Context<Services>, that: Context<R1>): Context<Services | R1>Services, function (type parameter) R1 in <Services, R1>(self: Context<Services>, that: Context<R1>): Context<Services | R1>R1>(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, R1>(self: Context<Services>, that: Context<R1>): Context<Services | R1>Services>, that: Context<R1>(parameter) that: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
that: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) R1 in <Services, R1>(self: Context<Services>, that: Context<R1>): Context<Services | R1>R1>): interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, R1>(self: Context<Services>, that: Context<R1>): Context<Services | R1>Services | function (type parameter) R1 in <Services, R1>(self: Context<Services>, that: Context<R1>): Context<Services | R1>R1> => {
if (self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self.Context<in Services>.mapUnsafe: ReadonlyMap<string, any>mapUnsafe.ReadonlyMap<string, any>.size: numbersize === 0) return that: Context<R1>(parameter) that: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
that as any
if (that: Context<R1>(parameter) that: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
that.Context<in Services>.mapUnsafe: ReadonlyMap<string, any>mapUnsafe.ReadonlyMap<string, any>.size: numbersize === 0) return self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self as any
return const withMapUnsafe: <Services, B>(
self: Context<Services>,
f: (map: Map<string, any>) => void
) => Context<B>
withMapUnsafe(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self, (map: Map<string, any>map) => {
that: Context<R1>(parameter) that: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
that.Context<in Services>.mapUnsafe: ReadonlyMap<string, any>mapUnsafe.ReadonlyMap<string, any>.forEach(callbackfn: (value: any, key: string, map: ReadonlyMap<string, any>) => void, thisArg?: any): voidforEach((value: anyvalue, key: stringkey) => map: Map<string, any>map.Map<string, any>.set(key: string, value: any): Map<string, any>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(key: stringkey, value: anyvalue))
})
})
/**
* Merges any number of `Context`s into one.
*
* **When to use**
*
* Use when you need to combine a variadic list of contexts.
*
* **Details**
*
* When multiple contexts contain the same service key, the service from the
* last context with that key is kept.
*
* **Example** (Merging multiple contexts)
*
* ```ts
* import { Context } from "effect"
* import * as assert from "node:assert"
*
* const Port = Context.Service<{ PORT: number }>("Port")
* const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout")
* const Host = Context.Service<{ HOST: string }>("Host")
*
* const firstContext = Context.make(Port, { PORT: 8080 })
* const secondContext = Context.make(Timeout, { TIMEOUT: 5000 })
* const thirdContext = Context.make(Host, { HOST: "localhost" })
*
* const context = Context.mergeAll(
* firstContext,
* secondContext,
* thirdContext
* )
*
* assert.deepStrictEqual(Context.get(context, Port), { PORT: 8080 })
* assert.deepStrictEqual(Context.get(context, Timeout), { TIMEOUT: 5000 })
* assert.deepStrictEqual(Context.get(context, Host), { HOST: "localhost" })
* ```
*
* @see {@link merge} for merging two contexts
*
* @category combining
* @since 3.12.0
*/
export const const mergeAll: <
T extends Array<unknown>
>(
...ctxs: { [K in keyof T]: Context<T[K]> }
) => Context<T[number]>
Merges any number of Contexts into one.
When to use
Use when you need to combine a variadic list of contexts.
Details
When multiple contexts contain the same service key, the service from the
last context with that key is kept.
Example (Merging multiple contexts)
import { Context } from "effect"
import * as assert from "node:assert"
const Port = Context.Service<{ PORT: number }>("Port")
const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout")
const Host = Context.Service<{ HOST: string }>("Host")
const firstContext = Context.make(Port, { PORT: 8080 })
const secondContext = Context.make(Timeout, { TIMEOUT: 5000 })
const thirdContext = Context.make(Host, { HOST: "localhost" })
const context = Context.mergeAll(
firstContext,
secondContext,
thirdContext
)
assert.deepStrictEqual(Context.get(context, Port), { PORT: 8080 })
assert.deepStrictEqual(Context.get(context, Timeout), { TIMEOUT: 5000 })
assert.deepStrictEqual(Context.get(context, Host), { HOST: "localhost" })
mergeAll = <function (type parameter) T in <T extends Array<unknown>>(...ctxs: { [K in keyof T]: Context<T[K]>; }): Context<T[number]>T extends interface Array<T>Array<unknown>>(
...ctxs: [...{ [K in keyof T]: Context<T[K]> }](parameter) ctxs: {
length: number;
toString: () => string;
toLocaleString: { (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string };
pop: () => { [K in keyof T]: Context<T[K]>; }[number] | undefined;
push: (...items: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => number;
concat: { (...items: Array<ConcatArray<{ [K in keyof T]: Context<T[K]>; }[number]>>): Array<{ [K in keyof T]: Context<T[K]>; }[number]>; (...items: Array<{ [K in keyof T]: Context<T[K]>; }[number] | ConcatArray<{ [K in keyof T]: Context<T[K]>; }[n…;
join: (separator?: string) => string;
reverse: () => Array<{ [K in keyof T]: Context<T[K]>; }[number]>;
shift: () => { [K in keyof T]: Context<T[K]>; }[number] | undefined;
slice: (start?: number, end?: number) => Array<{ [K in keyof T]: Context<T[K]>; }[number]>;
sort: (compareFn?: ((a: { [K in keyof T]: Context<T[K]>; }[number], b: { [K in keyof T]: Context<T[K]>; }[number]) => number) | undefined) => [...{ [K in keyof T]: Context<T[K]>; }];
splice: { (start: number, deleteCount?: number): Array<{ [K in keyof T]: Context<T[K]>; }[number]>; (start: number, deleteCount: number, ...items: Array<{ [K in keyof T]: Context<T[K]>; }[number]>): Array<{ [K in keyof T]: Context<T[K]>; }[number]…;
unshift: (...items: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => number;
indexOf: (searchElement: { [K in keyof T]: Context<T[K]>; }[number], fromIndex?: number) => number;
lastIndexOf: (searchElement: { [K in keyof T]: Context<T[K]>; }[number], fromIndex?: number) => number;
every: { (predicate: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => value is S, thisArg?: any): this is S[]; (predicate: (value: { [K in keyof T]: Context<T[K]>; }[n…;
some: (predicate: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => unknown, thisArg?: any) => boolean;
forEach: (callbackfn: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => void, thisArg?: any) => void;
map: (callbackfn: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => U, thisArg?: any) => Array<U>;
filter: { (predicate: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => value is S, thisArg?: any): Array<S>; (predicate: (value: { [K in keyof T]: Context<T[K]>; }[numb…;
reduce: { (callbackfn: (previousValue: { [K in keyof T]: Context<T[K]>; }[number], currentValue: { [K in keyof T]: Context<T[K]>; }[number], currentIndex: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => { [K in keyof T]: Conte…;
reduceRight: { (callbackfn: (previousValue: { [K in keyof T]: Context<T[K]>; }[number], currentValue: { [K in keyof T]: Context<T[K]>; }[number], currentIndex: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => { [K in keyof T]: Conte…;
find: { (predicate: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, obj: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => value is S, thisArg?: any): S | undefined; (predicate: (value: { [K in keyof T]: Context<T[K]>; }[n…;
findIndex: (predicate: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, obj: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => unknown, thisArg?: any) => number;
fill: (value: { [K in keyof T]: Context<T[K]>; }[number], start?: number, end?: number) => [...{ [K in keyof T]: Context<T[K]>; }];
copyWithin: (target: number, start: number, end?: number) => [...{ [K in keyof T]: Context<T[K]>; }];
entries: () => ArrayIterator<[number, { [K in keyof T]: Context<T[K]>; }[number]]>;
keys: () => ArrayIterator<number>;
values: () => ArrayIterator<{ [K in keyof T]: Context<T[K]>; }[number]>;
includes: (searchElement: { [K in keyof T]: Context<T[K]>; }[number], fromIndex?: number) => boolean;
flatMap: (callback: (this: This, value: { [K in keyof T]: Context<T[K]>; }[number], index: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => U | ReadonlyArray<U>, thisArg?: This | undefined) => Array<U>;
flat: (this: A, depth?: D | undefined) => Array<FlatArray<A, D>>;
at: (index: number) => { [K in keyof T]: Context<T[K]>; }[number] | undefined;
findLast: { (predicate: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => value is S, thisArg?: any): S | undefined; (predicate: (value: { [K in keyof T]: Context<T[K]>; }…;
findLastIndex: (predicate: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => unknown, thisArg?: any) => number;
toReversed: () => Array<{ [K in keyof T]: Context<T[K]>; }[number]>;
toSorted: (compareFn?: ((a: { [K in keyof T]: Context<T[K]>; }[number], b: { [K in keyof T]: Context<T[K]>; }[number]) => number) | undefined) => Array<{ [K in keyof T]: Context<T[K]>; }[number]>;
toSpliced: { (start: number, deleteCount: number, ...items: Array<{ [K in keyof T]: Context<T[K]>; }[number]>): Array<{ [K in keyof T]: Context<T[K]>; }[number]>; (start: number, deleteCount?: number): Array<{ [K in keyof T]: Context<T[K]>; }[number]…;
with: (index: number, value: { [K in keyof T]: Context<T[K]>; }[number]) => Array<{ [K in keyof T]: Context<T[K]>; }[number]>;
}
ctxs: [...{ [function (type parameter) KK in keyof function (type parameter) T in <T extends Array<unknown>>(...ctxs: { [K in keyof T]: Context<T[K]>; }): Context<T[number]>T]: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) T in <T extends Array<unknown>>(...ctxs: { [K in keyof T]: Context<T[K]>; }): Context<T[number]>T[function (type parameter) KK]> }]
): interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) T in <T extends Array<unknown>>(...ctxs: { [K in keyof T]: Context<T[K]>; }): Context<T[number]>T[number]> => {
const const map: Map<any, any>map = new var Map: MapConstructor
new () => Map<any, any> (+3 overloads)
Map()
for (let let i: numberi = 0; let i: numberi < ctxs: [...{ [K in keyof T]: Context<T[K]> }](parameter) ctxs: {
length: number;
toString: () => string;
toLocaleString: { (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string };
pop: () => { [K in keyof T]: Context<T[K]>; }[number] | undefined;
push: (...items: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => number;
concat: { (...items: Array<ConcatArray<{ [K in keyof T]: Context<T[K]>; }[number]>>): Array<{ [K in keyof T]: Context<T[K]>; }[number]>; (...items: Array<{ [K in keyof T]: Context<T[K]>; }[number] | ConcatArray<{ [K in keyof T]: Context<T[K]>; }[n…;
join: (separator?: string) => string;
reverse: () => Array<{ [K in keyof T]: Context<T[K]>; }[number]>;
shift: () => { [K in keyof T]: Context<T[K]>; }[number] | undefined;
slice: (start?: number, end?: number) => Array<{ [K in keyof T]: Context<T[K]>; }[number]>;
sort: (compareFn?: ((a: { [K in keyof T]: Context<T[K]>; }[number], b: { [K in keyof T]: Context<T[K]>; }[number]) => number) | undefined) => [...{ [K in keyof T]: Context<T[K]>; }];
splice: { (start: number, deleteCount?: number): Array<{ [K in keyof T]: Context<T[K]>; }[number]>; (start: number, deleteCount: number, ...items: Array<{ [K in keyof T]: Context<T[K]>; }[number]>): Array<{ [K in keyof T]: Context<T[K]>; }[number]…;
unshift: (...items: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => number;
indexOf: (searchElement: { [K in keyof T]: Context<T[K]>; }[number], fromIndex?: number) => number;
lastIndexOf: (searchElement: { [K in keyof T]: Context<T[K]>; }[number], fromIndex?: number) => number;
every: { (predicate: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => value is S, thisArg?: any): this is S[]; (predicate: (value: { [K in keyof T]: Context<T[K]>; }[n…;
some: (predicate: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => unknown, thisArg?: any) => boolean;
forEach: (callbackfn: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => void, thisArg?: any) => void;
map: (callbackfn: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => U, thisArg?: any) => Array<U>;
filter: { (predicate: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => value is S, thisArg?: any): Array<S>; (predicate: (value: { [K in keyof T]: Context<T[K]>; }[numb…;
reduce: { (callbackfn: (previousValue: { [K in keyof T]: Context<T[K]>; }[number], currentValue: { [K in keyof T]: Context<T[K]>; }[number], currentIndex: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => { [K in keyof T]: Conte…;
reduceRight: { (callbackfn: (previousValue: { [K in keyof T]: Context<T[K]>; }[number], currentValue: { [K in keyof T]: Context<T[K]>; }[number], currentIndex: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => { [K in keyof T]: Conte…;
find: { (predicate: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, obj: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => value is S, thisArg?: any): S | undefined; (predicate: (value: { [K in keyof T]: Context<T[K]>; }[n…;
findIndex: (predicate: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, obj: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => unknown, thisArg?: any) => number;
fill: (value: { [K in keyof T]: Context<T[K]>; }[number], start?: number, end?: number) => [...{ [K in keyof T]: Context<T[K]>; }];
copyWithin: (target: number, start: number, end?: number) => [...{ [K in keyof T]: Context<T[K]>; }];
entries: () => ArrayIterator<[number, { [K in keyof T]: Context<T[K]>; }[number]]>;
keys: () => ArrayIterator<number>;
values: () => ArrayIterator<{ [K in keyof T]: Context<T[K]>; }[number]>;
includes: (searchElement: { [K in keyof T]: Context<T[K]>; }[number], fromIndex?: number) => boolean;
flatMap: (callback: (this: This, value: { [K in keyof T]: Context<T[K]>; }[number], index: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => U | ReadonlyArray<U>, thisArg?: This | undefined) => Array<U>;
flat: (this: A, depth?: D | undefined) => Array<FlatArray<A, D>>;
at: (index: number) => { [K in keyof T]: Context<T[K]>; }[number] | undefined;
findLast: { (predicate: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => value is S, thisArg?: any): S | undefined; (predicate: (value: { [K in keyof T]: Context<T[K]>; }…;
findLastIndex: (predicate: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => unknown, thisArg?: any) => number;
toReversed: () => Array<{ [K in keyof T]: Context<T[K]>; }[number]>;
toSorted: (compareFn?: ((a: { [K in keyof T]: Context<T[K]>; }[number], b: { [K in keyof T]: Context<T[K]>; }[number]) => number) | undefined) => Array<{ [K in keyof T]: Context<T[K]>; }[number]>;
toSpliced: { (start: number, deleteCount: number, ...items: Array<{ [K in keyof T]: Context<T[K]>; }[number]>): Array<{ [K in keyof T]: Context<T[K]>; }[number]>; (start: number, deleteCount?: number): Array<{ [K in keyof T]: Context<T[K]>; }[number]…;
with: (index: number, value: { [K in keyof T]: Context<T[K]>; }[number]) => Array<{ [K in keyof T]: Context<T[K]>; }[number]>;
}
ctxs.length: numberlength; let i: numberi++) {
ctxs: [...{ [K in keyof T]: Context<T[K]> }](parameter) ctxs: {
length: number;
toString: () => string;
toLocaleString: { (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string };
pop: () => { [K in keyof T]: Context<T[K]>; }[number] | undefined;
push: (...items: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => number;
concat: { (...items: Array<ConcatArray<{ [K in keyof T]: Context<T[K]>; }[number]>>): Array<{ [K in keyof T]: Context<T[K]>; }[number]>; (...items: Array<{ [K in keyof T]: Context<T[K]>; }[number] | ConcatArray<{ [K in keyof T]: Context<T[K]>; }[n…;
join: (separator?: string) => string;
reverse: () => Array<{ [K in keyof T]: Context<T[K]>; }[number]>;
shift: () => { [K in keyof T]: Context<T[K]>; }[number] | undefined;
slice: (start?: number, end?: number) => Array<{ [K in keyof T]: Context<T[K]>; }[number]>;
sort: (compareFn?: ((a: { [K in keyof T]: Context<T[K]>; }[number], b: { [K in keyof T]: Context<T[K]>; }[number]) => number) | undefined) => [...{ [K in keyof T]: Context<T[K]>; }];
splice: { (start: number, deleteCount?: number): Array<{ [K in keyof T]: Context<T[K]>; }[number]>; (start: number, deleteCount: number, ...items: Array<{ [K in keyof T]: Context<T[K]>; }[number]>): Array<{ [K in keyof T]: Context<T[K]>; }[number]…;
unshift: (...items: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => number;
indexOf: (searchElement: { [K in keyof T]: Context<T[K]>; }[number], fromIndex?: number) => number;
lastIndexOf: (searchElement: { [K in keyof T]: Context<T[K]>; }[number], fromIndex?: number) => number;
every: { (predicate: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => value is S, thisArg?: any): this is S[]; (predicate: (value: { [K in keyof T]: Context<T[K]>; }[n…;
some: (predicate: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => unknown, thisArg?: any) => boolean;
forEach: (callbackfn: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => void, thisArg?: any) => void;
map: (callbackfn: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => U, thisArg?: any) => Array<U>;
filter: { (predicate: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => value is S, thisArg?: any): Array<S>; (predicate: (value: { [K in keyof T]: Context<T[K]>; }[numb…;
reduce: { (callbackfn: (previousValue: { [K in keyof T]: Context<T[K]>; }[number], currentValue: { [K in keyof T]: Context<T[K]>; }[number], currentIndex: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => { [K in keyof T]: Conte…;
reduceRight: { (callbackfn: (previousValue: { [K in keyof T]: Context<T[K]>; }[number], currentValue: { [K in keyof T]: Context<T[K]>; }[number], currentIndex: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => { [K in keyof T]: Conte…;
find: { (predicate: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, obj: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => value is S, thisArg?: any): S | undefined; (predicate: (value: { [K in keyof T]: Context<T[K]>; }[n…;
findIndex: (predicate: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, obj: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => unknown, thisArg?: any) => number;
fill: (value: { [K in keyof T]: Context<T[K]>; }[number], start?: number, end?: number) => [...{ [K in keyof T]: Context<T[K]>; }];
copyWithin: (target: number, start: number, end?: number) => [...{ [K in keyof T]: Context<T[K]>; }];
entries: () => ArrayIterator<[number, { [K in keyof T]: Context<T[K]>; }[number]]>;
keys: () => ArrayIterator<number>;
values: () => ArrayIterator<{ [K in keyof T]: Context<T[K]>; }[number]>;
includes: (searchElement: { [K in keyof T]: Context<T[K]>; }[number], fromIndex?: number) => boolean;
flatMap: (callback: (this: This, value: { [K in keyof T]: Context<T[K]>; }[number], index: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => U | ReadonlyArray<U>, thisArg?: This | undefined) => Array<U>;
flat: (this: A, depth?: D | undefined) => Array<FlatArray<A, D>>;
at: (index: number) => { [K in keyof T]: Context<T[K]>; }[number] | undefined;
findLast: { (predicate: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => value is S, thisArg?: any): S | undefined; (predicate: (value: { [K in keyof T]: Context<T[K]>; }…;
findLastIndex: (predicate: (value: { [K in keyof T]: Context<T[K]>; }[number], index: number, array: Array<{ [K in keyof T]: Context<T[K]>; }[number]>) => unknown, thisArg?: any) => number;
toReversed: () => Array<{ [K in keyof T]: Context<T[K]>; }[number]>;
toSorted: (compareFn?: ((a: { [K in keyof T]: Context<T[K]>; }[number], b: { [K in keyof T]: Context<T[K]>; }[number]) => number) | undefined) => Array<{ [K in keyof T]: Context<T[K]>; }[number]>;
toSpliced: { (start: number, deleteCount: number, ...items: Array<{ [K in keyof T]: Context<T[K]>; }[number]>): Array<{ [K in keyof T]: Context<T[K]>; }[number]>; (start: number, deleteCount?: number): Array<{ [K in keyof T]: Context<T[K]>; }[number]…;
with: (index: number, value: { [K in keyof T]: Context<T[K]>; }[number]) => Array<{ [K in keyof T]: Context<T[K]>; }[number]>;
}
ctxs[let i: numberi].Context<in Services>.mapUnsafe: ReadonlyMap<string, any>mapUnsafe.ReadonlyMap<string, any>.forEach(callbackfn: (value: any, key: string, map: ReadonlyMap<string, any>) => void, thisArg?: any): voidforEach((value: anyvalue, key: stringkey) => {
const map: Map<any, any>map.Map<any, any>.set(key: any, value: any): Map<any, any>Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set(key: stringkey, value: anyvalue)
})
}
return const makeUnsafe: <Services = never>(
mapUnsafe: ReadonlyMap<string, any>
) => Context<Services>
Creates a Context from an existing service map.
When to use
Use when constructing a low-level Context from a trusted map whose lifecycle
you control.
Gotchas
This is unsafe because later mutation of the provided map can affect the
created Context. Prefer empty, make, add, or merge for normal
Context construction.
Example (Creating a context from a map)
import { Context } from "effect"
// Create a context from a Map (unsafe)
const map = new Map([
["Logger", { log: (msg: string) => console.log(msg) }]
])
const context = Context.makeUnsafe(map)
makeUnsafe(const map: Map<any, any>map)
}
/**
* Returns a new `Context` that contains only the specified services.
*
* **When to use**
*
* Use when you want to keep an allowlist of services in a `Context`.
*
* **Example** (Picking services from a context)
*
* ```ts
* import { Context, Option, pipe } from "effect"
* import * as assert from "node:assert"
*
* const Port = Context.Service<{ PORT: number }>("Port")
* const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout")
*
* const someContext = pipe(
* Context.make(Port, { PORT: 8080 }),
* Context.add(Timeout, { TIMEOUT: 5000 })
* )
*
* const context = pipe(someContext, Context.pick(Port))
*
* assert.deepStrictEqual(
* Context.getOption(context, Port),
* Option.some({ PORT: 8080 })
* )
* assert.deepStrictEqual(Context.getOption(context, Timeout), Option.none())
* ```
*
* @see {@link omit} for removing selected services
*
* @category filtering
* @since 2.0.0
*/
export const const pick: <
S extends ReadonlyArray<Key<any, any>>
>(
...services: S
) => <Services>(
self: Context<Services>
) => Context<
Services & Service.Identifier<S[number]>
>
Returns a new Context that contains only the specified services.
When to use
Use when you want to keep an allowlist of services in a Context.
Example (Picking services from a context)
import { Context, Option, pipe } from "effect"
import * as assert from "node:assert"
const Port = Context.Service<{ PORT: number }>("Port")
const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout")
const someContext = pipe(
Context.make(Port, { PORT: 8080 }),
Context.add(Timeout, { TIMEOUT: 5000 })
)
const context = pipe(someContext, Context.pick(Port))
assert.deepStrictEqual(
Context.getOption(context, Port),
Option.some({ PORT: 8080 })
)
assert.deepStrictEqual(Context.getOption(context, Timeout), Option.none())
pick = <function (type parameter) S in <S extends ReadonlyArray<Key<any, any>>>(...services: S): <Services>(self: Context<Services>) => Context<Services & Service.Identifier<S[number]>>S extends interface ReadonlyArray<T>ReadonlyArray<interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<any, any>>>(
...services: S extends ReadonlyArray<Key<any, any>>services: function (type parameter) S in <S extends ReadonlyArray<Key<any, any>>>(...services: S): <Services>(self: Context<Services>) => Context<Services & Service.Identifier<S[number]>>S
) =>
<function (type parameter) Services in <Services>(self: Context<Services>): Context<Services & Service.Identifier<S[number]>>Services>(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services>(self: Context<Services>): Context<Services & Service.Identifier<S[number]>>Services>): interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services>(self: Context<Services>): Context<Services & Service.Identifier<S[number]>>Services & Service.type Service<in out Identifier, in out Shape>.Identifier<T> = T extends Key<infer I, infer _S> ? I : neverExtracts the identifier, or requirement type, associated with a Context
service key.
Example (Extracting a service identifier)
import { Context } from "effect"
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
// Extract the identifier type from a key
type DatabaseId = Context.Service.Identifier<typeof Database>
// DatabaseId is the identifier type
Identifier<function (type parameter) S in <S extends ReadonlyArray<Key<any, any>>>(...services: S): <Services>(self: Context<Services>) => Context<Services & Service.Identifier<S[number]>>S[number]>> =>
const withMapUnsafe: <Services, B>(
self: Context<Services>,
f: (map: Map<string, any>) => void
) => Context<B>
withMapUnsafe(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self, (map: Map<string, any>map) => {
const const keySet: Set<string>keySet = new var Set: SetConstructor
new <string>(iterable?: Iterable<string> | null | undefined) => Set<string> (+1 overload)
Set(services: S extends ReadonlyArray<Key<any, any>>services.ReadonlyArray<Key<any, any>>.map<string>(callbackfn: (value: Key<any, any>, index: number, array: readonly Key<any, any>[]) => string, thisArg?: any): string[]Calls a defined callback function on each element of an array, and returns an array that contains the results.
map((key: Key<any, any>(parameter) key: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
key) => key: Key<any, any>(parameter) key: {
Identifier: Identifier;
Service: Shape;
key: string;
stack: string | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
key.Key<out Identifier, out Shape>.key: stringkey))
map: Map<string, any>map.Map<string, any>.forEach(callbackfn: (value: any, key: string, map: Map<string, any>) => void, thisArg?: any): voidExecutes a provided function once per each key/value pair in the Map, in insertion order.
forEach((_: any_, key: stringkey) => {
if (const keySet: Set<string>keySet.Set<string>.has(value: string): booleanhas(key: stringkey)) return
map: Map<string, any>map.Map<string, any>.delete(key: string): booleandelete(key: stringkey)
})
})
/**
* Returns a new `Context` with the specified service keys removed.
*
* **When to use**
*
* Use when you want to remove a denylist of services from a `Context`.
*
* **Example** (Omitting services from a context)
*
* ```ts
* import { Context, Option, pipe } from "effect"
* import * as assert from "node:assert"
*
* const Port = Context.Service<{ PORT: number }>("Port")
* const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout")
*
* const someContext = pipe(
* Context.make(Port, { PORT: 8080 }),
* Context.add(Timeout, { TIMEOUT: 5000 })
* )
*
* const context = pipe(someContext, Context.omit(Timeout))
*
* assert.deepStrictEqual(
* Context.getOption(context, Port),
* Option.some({ PORT: 8080 })
* )
* assert.deepStrictEqual(Context.getOption(context, Timeout), Option.none())
* ```
*
* @see {@link pick} for keeping selected services
*
* @category filtering
* @since 2.0.0
*/
export const const omit: <
S extends ReadonlyArray<Key<any, any>>
>(
...keys: S
) => <Services>(
self: Context<Services>
) => Context<
Exclude<Services, Service.Identifier<S[number]>>
>
Returns a new Context with the specified service keys removed.
When to use
Use when you want to remove a denylist of services from a Context.
Example (Omitting services from a context)
import { Context, Option, pipe } from "effect"
import * as assert from "node:assert"
const Port = Context.Service<{ PORT: number }>("Port")
const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout")
const someContext = pipe(
Context.make(Port, { PORT: 8080 }),
Context.add(Timeout, { TIMEOUT: 5000 })
)
const context = pipe(someContext, Context.omit(Timeout))
assert.deepStrictEqual(
Context.getOption(context, Port),
Option.some({ PORT: 8080 })
)
assert.deepStrictEqual(Context.getOption(context, Timeout), Option.none())
omit = <function (type parameter) S in <S extends ReadonlyArray<Key<any, any>>>(...keys: S): <Services>(self: Context<Services>) => Context<Exclude<Services, Service.Identifier<S[number]>>>S extends interface ReadonlyArray<T>ReadonlyArray<interface Key<out Identifier, out Shape>Typed identifier for a service stored in a Context.
When to use
Use as the typed handle for storing, retrieving, and requiring a specific
service in a Context.
Details
Identifier tracks the requirement in Effect types, while Shape is the
service implementation retrieved by the key. A key is also an Effect value,
so yielding it inside Effect.gen retrieves the service from the current
fiber context.
Key<any, any>>>(
...keys: S extends ReadonlyArray<Key<any, any>>keys: function (type parameter) S in <S extends ReadonlyArray<Key<any, any>>>(...keys: S): <Services>(self: Context<Services>) => Context<Exclude<Services, Service.Identifier<S[number]>>>S
) =>
<function (type parameter) Services in <Services>(self: Context<Services>): Context<Exclude<Services, Service.Identifier<S[number]>>>Services>(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services>(self: Context<Services>): Context<Exclude<Services, Service.Identifier<S[number]>>>Services>): interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<type Exclude<T, U> = T extends U
? never
: T
Exclude from T those types that are assignable to U
Exclude<function (type parameter) Services in <Services>(self: Context<Services>): Context<Exclude<Services, Service.Identifier<S[number]>>>Services, Service.type Service<in out Identifier, in out Shape>.Identifier<T> = T extends Key<infer I, infer _S> ? I : neverExtracts the identifier, or requirement type, associated with a Context
service key.
Example (Extracting a service identifier)
import { Context } from "effect"
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
// Extract the identifier type from a key
type DatabaseId = Context.Service.Identifier<typeof Database>
// DatabaseId is the identifier type
Identifier<function (type parameter) S in <S extends ReadonlyArray<Key<any, any>>>(...keys: S): <Services>(self: Context<Services>) => Context<Exclude<Services, Service.Identifier<S[number]>>>S[number]>>> =>
const withMapUnsafe: <Services, B>(
self: Context<Services>,
f: (map: Map<string, any>) => void
) => Context<B>
withMapUnsafe(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self, (map: Map<string, any>map) => {
for (let let i: numberi = 0; let i: numberi < keys: S extends ReadonlyArray<Key<any, any>>keys.ReadonlyArray<Key<any, any>>.length: numberGets the length of the array. This is a number one higher than the highest element defined in an array.
length; let i: numberi++) {
map: Map<string, any>map.Map<string, any>.delete(key: string): booleandelete(keys: S extends ReadonlyArray<Key<any, any>>keys[let i: numberi].Key<out Identifier, out Shape>.key: stringkey)
}
})
/**
* Performs a series of mutations on a `Context`. Prevents unnecessary copying
* of the underlying map when multiple mutations are needed.
*
* **When to use**
*
* Use to apply several `Context` transformations in one callback while copying
* the underlying service map only once.
*
* @see {@link add} for adding or replacing a service
* @see {@link addOrOmit} for adding or removing a service from an `Option`
* @see {@link merge} for combining two contexts
* @see {@link pick} for keeping selected services
* @see {@link omit} for removing selected services
*
* @category mutations
* @since 4.0.0
*/
export const const mutate: {
<Services, B>(
f: (context: Context<Services>) => Context<B>
): <Services>(
self: Context<Services>
) => Context<B>
<Services, B>(
self: Context<Services>,
f: (context: Context<Services>) => Context<B>
): Context<B>
}
Performs a series of mutations on a Context. Prevents unnecessary copying
of the underlying map when multiple mutations are needed.
When to use
Use to apply several Context transformations in one callback while copying
the underlying service map only once.
mutate: {
<function (type parameter) Services in <Services, B>(f: (context: Context<Services>) => Context<B>): <Services>(self: Context<Services>) => Context<B>Services, function (type parameter) B in <Services, B>(f: (context: Context<Services>) => Context<B>): <Services>(self: Context<Services>) => Context<B>B>(
f: (
context: Context<Services>
) => Context<B>
f: (context: Context<Services>(parameter) context: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
context: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, B>(f: (context: Context<Services>) => Context<B>): <Services>(self: Context<Services>) => Context<B>Services>) => interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) B in <Services, B>(f: (context: Context<Services>) => Context<B>): <Services>(self: Context<Services>) => Context<B>B>
): <function (type parameter) Services in <Services>(self: Context<Services>): Context<B>Services>(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services>(self: Context<Services>): Context<B>Services>) => interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) B in <Services, B>(f: (context: Context<Services>) => Context<B>): <Services>(self: Context<Services>) => Context<B>B>
<function (type parameter) Services in <Services, B>(self: Context<Services>, f: (context: Context<Services>) => Context<B>): Context<B>Services, function (type parameter) B in <Services, B>(self: Context<Services>, f: (context: Context<Services>) => Context<B>): Context<B>B>(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, B>(self: Context<Services>, f: (context: Context<Services>) => Context<B>): Context<B>Services>, f: (
context: Context<Services>
) => Context<B>
f: (context: Context<Services>(parameter) context: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
context: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, B>(self: Context<Services>, f: (context: Context<Services>) => Context<B>): Context<B>Services>) => interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) B in <Services, B>(self: Context<Services>, f: (context: Context<Services>) => Context<B>): Context<B>B>): interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) B in <Services, B>(self: Context<Services>, f: (context: Context<Services>) => Context<B>): Context<B>B>
} = dual<(...args: Array<any>) => any, <Services, B>(self: Context<Services>, f: (context: Context<Services>) => Context<B>) => Context<B>>(arity: 2, body: <Services, B>(self: Context<Services>, f: (context: Context<Services>) => Context<B>) => Context<B>): ((...args: Array<any>) => any) & (<Services, B>(self: Context<Services>, f: (context: Context<Services>) => Context<B>) => Context<B>) (+1 overload)Creates a function that can be called in data-first style or data-last
(pipe-friendly) style.
When to use
Use to expose one implementation through both direct and pipe-friendly
call styles.
Details
Pass either the arity of the uncurried function or a predicate that decides
whether the current call is data-first. Arity is the common case. Use a
predicate when optional arguments make arity ambiguous.
Example (Selecting data-first or data-last style by arity)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(2, (self, that) => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Defining overloads with call signatures)
import { Function, pipe } from "effect"
const sum: {
(that: number): (self: number) => number
(self: number, that: number): number
} = Function.dual(2, (self: number, that: number): number => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Selecting data-first or data-last style with a predicate)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(
(args) => args.length === 2,
(self, that) => self + that
)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
dual(
2,
<function (type parameter) Services in <Services, B>(self: Context<Services>, f: (context: Context<Services>) => Context<B>): Context<B>Services, function (type parameter) B in <Services, B>(self: Context<Services>, f: (context: Context<Services>) => Context<B>): Context<B>B>(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, B>(self: Context<Services>, f: (context: Context<Services>) => Context<B>): Context<B>Services>, f: (
context: Context<Services>
) => Context<B>
f: (context: Context<Services>(parameter) context: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
context: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, B>(self: Context<Services>, f: (context: Context<Services>) => Context<B>): Context<B>Services>) => interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) B in <Services, B>(self: Context<Services>, f: (context: Context<Services>) => Context<B>): Context<B>B>): interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) B in <Services, B>(self: Context<Services>, f: (context: Context<Services>) => Context<B>): Context<B>B> => {
const const next: Context<Services>const next: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
next = const makeUnsafe: <Services = never>(
mapUnsafe: ReadonlyMap<string, any>
) => Context<Services>
Creates a Context from an existing service map.
When to use
Use when constructing a low-level Context from a trusted map whose lifecycle
you control.
Gotchas
This is unsafe because later mutation of the provided map can affect the
created Context. Prefer empty, make, add, or merge for normal
Context construction.
Example (Creating a context from a map)
import { Context } from "effect"
// Create a context from a Map (unsafe)
const map = new Map([
["Logger", { log: (msg: string) => console.log(msg) }]
])
const context = Context.makeUnsafe(map)
makeUnsafe<function (type parameter) Services in <Services, B>(self: Context<Services>, f: (context: Context<Services>) => Context<B>): Context<B>Services>(new var Map: MapConstructor
new <string, any>(iterable?: Iterable<readonly [string, any]> | null | undefined) => Map<string, any> (+3 overloads)
Map(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self.Context<in Services>.mapUnsafe: ReadonlyMap<string, any>mapUnsafe))
const next: Context<Services>const next: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
next.Context<in Services>.mutable: booleanmutable = true
const const result: Context<B>const result: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
result = f: (
context: Context<Services>
) => Context<B>
f(const next: Context<Services>const next: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
next)
const result: Context<B>const result: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
result.Context<in Services>.mutable: booleanmutable = false
return const result: Context<B>const result: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
result
}
)
const const withMapUnsafe: <Services, B>(
self: Context<Services>,
f: (map: Map<string, any>) => void
) => Context<B>
withMapUnsafe = <function (type parameter) Services in <Services, B>(self: Context<Services>, f: (map: Map<string, any>) => void): Context<B>Services, function (type parameter) B in <Services, B>(self: Context<Services>, f: (map: Map<string, any>) => void): Context<B>B>(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self: interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) Services in <Services, B>(self: Context<Services>, f: (map: Map<string, any>) => void): Context<B>Services>, f: (map: Map<string, any>) => voidf: (map: Map<string, any>map: interface Map<K, V>Map<string, any>) => void): interface Context<in Services>Immutable collection of service implementations used for dependency
injection in Effect programs.
Details
The type parameter tracks the service identifiers available in the context.
At runtime, services are stored by each key's string key.
Example (Creating a context with multiple services)
import { Context } from "effect"
// Create a context with multiple services
const Logger = Context.Service<{ log: (msg: string) => void }>("Logger")
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
const context = Context.make(Logger, {
log: (msg: string) => console.log(msg)
})
.pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` }))
Context<function (type parameter) B in <Services, B>(self: Context<Services>, f: (map: Map<string, any>) => void): Context<B>B> => {
if (self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self.Context<in Services>.mutable: booleanmutable) {
f: (map: Map<string, any>) => voidf(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self.Context<in Services>.mapUnsafe: ReadonlyMap<string, any>mapUnsafe as any)
return self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self as any
}
const const map: Map<string, any>map = new var Map: MapConstructor
new <string, any>(iterable?: Iterable<readonly [string, any]> | null | undefined) => Map<string, any> (+3 overloads)
Map(self: Context<Services>(parameter) self: {
mapUnsafe: ReadonlyMap<string, any>;
mutable: boolean;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
self.Context<in Services>.mapUnsafe: ReadonlyMap<string, any>mapUnsafe)
f: (map: Map<string, any>) => voidf(const map: Map<string, any>map)
return const makeUnsafe: <Services = never>(
mapUnsafe: ReadonlyMap<string, any>
) => Context<Services>
Creates a Context from an existing service map.
When to use
Use when constructing a low-level Context from a trusted map whose lifecycle
you control.
Gotchas
This is unsafe because later mutation of the provided map can affect the
created Context. Prefer empty, make, add, or merge for normal
Context construction.
Example (Creating a context from a map)
import { Context } from "effect"
// Create a context from a Map (unsafe)
const map = new Map([
["Logger", { log: (msg: string) => console.log(msg) }]
])
const context = Context.makeUnsafe(map)
makeUnsafe(const map: Map<string, any>map)
}
/**
* Creates a context key with a default value.
*
* **When to use**
*
* Use when you need to define a context key with a lazily computed default
* value.
*
* **Details**
*
* `Context.Reference` allows you to create a key that can hold a value. You
* can provide a default value for the service, which will automatically be used
* when the context is accessed, or override it with a custom implementation
* when needed. The default value is computed lazily and cached on the
* reference.
*
* **Example** (Creating references with default values)
*
* ```ts
* import { Context } from "effect"
*
* // Create a reference with a default value
* const LoggerRef = Context.Reference("Logger", {
* defaultValue: () => ({ log: (msg: string) => console.log(msg) })
* })
*
* // The reference provides the default value when accessed from an empty context
* const context = Context.empty()
* const logger = Context.get(context, LoggerRef)
*
* // You can also override the default value
* const customContext = Context.make(LoggerRef, {
* log: (msg: string) => `Custom: ${msg}`
* })
* const customLogger = Context.get(customContext, LoggerRef)
* ```
*
* @see {@link Service} for required services without default values
*
* @category references
* @since 3.11.0
*/
export const const Reference: <Service>(
key: string,
options: {
readonly defaultValue: () => Service
}
) => Reference<Service>
Service key with a lazily computed default value.
Details
When a Reference is requested from a Context that does not contain an
override, Context getters that resolve references return the cached default
value instead of failing.
Example (Defining a reference with a default value)
import { Context } from "effect"
// Define a reference with a default value
const LoggerRef: Context.Reference<{ log: (msg: string) => void }> =
Context.Reference("Logger", {
defaultValue: () => ({ log: (msg: string) => console.log(msg) })
})
// The reference can be used without explicit provision
const context = Context.empty()
const logger = Context.get(context, LoggerRef) // Uses default value
Creates a context key with a default value.
When to use
Use when you need to define a context key with a lazily computed default
value.
Details
Context.Reference allows you to create a key that can hold a value. You
can provide a default value for the service, which will automatically be used
when the context is accessed, or override it with a custom implementation
when needed. The default value is computed lazily and cached on the
reference.
Example (Creating references with default values)
import { Context } from "effect"
// Create a reference with a default value
const LoggerRef = Context.Reference("Logger", {
defaultValue: () => ({ log: (msg: string) => console.log(msg) })
})
// The reference provides the default value when accessed from an empty context
const context = Context.empty()
const logger = Context.get(context, LoggerRef)
// You can also override the default value
const customContext = Context.make(LoggerRef, {
log: (msg: string) => `Custom: ${msg}`
})
const customLogger = Context.get(customContext, LoggerRef)
Reference: <function (type parameter) Service in <Service>(key: string, options: {
readonly defaultValue: () => Service;
}): Reference<Service>
Service>(
key: stringkey: string,
options: {
readonly defaultValue: () => Service
}
options: { readonly defaultValue: () => ServicedefaultValue: () => function (type parameter) Service in <Service>(key: string, options: {
readonly defaultValue: () => Service;
}): Reference<Service>
Service }
) => interface Reference<in out Shape>Service key with a lazily computed default value.
Details
When a Reference is requested from a Context that does not contain an
override, Context getters that resolve references return the cached default
value instead of failing.
Example (Defining a reference with a default value)
import { Context } from "effect"
// Define a reference with a default value
const LoggerRef: Context.Reference<{ log: (msg: string) => void }> =
Context.Reference("Logger", {
defaultValue: () => ({ log: (msg: string) => console.log(msg) })
})
// The reference can be used without explicit provision
const context = Context.empty()
const logger = Context.get(context, LoggerRef) // Uses default value
Creates a context key with a default value.
When to use
Use when you need to define a context key with a lazily computed default
value.
Details
Context.Reference allows you to create a key that can hold a value. You
can provide a default value for the service, which will automatically be used
when the context is accessed, or override it with a custom implementation
when needed. The default value is computed lazily and cached on the
reference.
Example (Creating references with default values)
import { Context } from "effect"
// Create a reference with a default value
const LoggerRef = Context.Reference("Logger", {
defaultValue: () => ({ log: (msg: string) => console.log(msg) })
})
// The reference provides the default value when accessed from an empty context
const context = Context.empty()
const logger = Context.get(context, LoggerRef)
// You can also override the default value
const customContext = Context.make(LoggerRef, {
log: (msg: string) => `Custom: ${msg}`
})
const customLogger = Context.get(customContext, LoggerRef)
Reference<function (type parameter) Service in <Service>(key: string, options: {
readonly defaultValue: () => Service;
}): Reference<Service>
Service> = const Service: {
<Identifier, Shape = Identifier>(key: string): Service<Identifier, Shape>;
<Self, Shape>(): <const Identifier extends string, E, R = Types.unassigned, Args extends ReadonlyArray<any> = never>(id: Identifier, options?: {
readonly make: ((...args: Args) => Effect<Shape, E, R>) | Effect<Shape, E, R> | undefined;
} | undefined) => ServiceClass<Self, Identifier, Shape> & ([Types.unassigned] extends [R] ? unknown : {
readonly make: [Args] extends [never] ? Effect<Shape, E, R> : (...args: Args) => Effect<Shape, E, R>;
});
<Self>(): <const Identifier extends string, Make extends Effect<any, any, any> | ((...args: any) => Effect<any, any, any>)>(id: Identifier, options: {
readonly make: Make;
}) => ServiceClass<Self, Identifier, Make extends Effect<infer _A, infer _E, infer _R> | ((...args: infer _Args) => Effect<infer _A, infer _E, infer _R>) ? _A : never> & {
readonly make: Make;
};
}
Context key with helper methods for working with a service.
Details
context creates a one-service Context, use and useSync retrieve the
service from the current Effect context before applying a function, and of
is a type-level helper for service values.
Example (Defining a service key)
import { Context } from "effect"
// Define an identifier for a database service
const Database = Context.Service<{ query: (sql: string) => string }>(
"Database"
)
// The key can be used to store and retrieve services
const context = Context.make(Database, { query: (sql) => `Result: ${sql}` })
Creates a Context service key.
When to use
Use when you need to define a context service key for a dependency that must
be provided by the surrounding context.
Details
Call Context.Service("Key") for a function-style key, or use the two-stage
form Context.Service<Self, Shape>()("Key") for class-style service
declarations. The returned key can be yielded as an Effect and passed to
Context.make, Context.add, and the Context getter functions.
Gotchas
The string key is the runtime identity of the service. Reusing the same key
string for unrelated services makes them occupy the same slot in a
Context.
Example (Creating service keys)
import { Context } from "effect"
// Create a simple service
const Database = Context.Service<{
query: (sql: string) => string
}>("Database")
// Create a service class
class Config extends Context.Service<Config, {
port: number
}>()("Config") {}
// Use the services to create contexts
const db = Context.make(Database, {
query: (sql) => `Result: ${sql}`
})
const config = Context.make(Config, { port: 8080 })
Namespace containing utility types for Context service keys.
Example (Extracting service types)
import { Context } from "effect"
const Database = Context.Service<{
query: (sql: string) => string
}>("Database")
// Extract service type from a key
type DatabaseService = Context.Service.Shape<typeof Database>
// Extract identifier type from a key
type DatabaseId = Context.Service.Identifier<typeof Database>
Service as any