<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 | BGets 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"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()
})