Context.ts
Context.ts overview
Section titled “Context.ts overview”Stores Effect services in typed maps.
A Context holds service implementations under Context.Service or
Context.Reference keys, and its type records which keys are present.
Effects use contexts as their environment, so services can be provided once
instead of passed through every function call. This module includes helpers
for creating keys, building contexts, adding and reading services, merging
contexts, and selecting or removing services.
Since v4.0.0
Exports Grouped by Category
Section titled “Exports Grouped by Category”- adders
- combining
- constructors
- filtering
- getters
- guards
- models
- mutations
- references
- type IDs
- unsafe
- utils
adders
Section titled “adders”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 })See
addOrOmitfor adding or removing a service from anOption
Signature
declare 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>}Since v2.0.0
addOrOmit
Section titled “addOrOmit”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()))See
addfor always storing a service value
Signature
declare 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>}Since v4.0.0
combining
Section titled “combining”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 })See
mergeAllfor merging more than two contexts at once
Signature
declare const merge: { <R1>(that: Context<R1>): <Services>(self: Context<Services>) => Context<R1 | Services> <Services, R1>(self: Context<Services>, that: Context<R1>): Context<Services | R1>}Since v2.0.0
mergeAll
Section titled “mergeAll”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" })See
mergefor merging two contexts
Signature
declare const mergeAll: <T extends Array<unknown>>(...ctxs: { [K in keyof T]: Context<T[K]> }) => Context<T[number]>Since v3.12.0
constructors
Section titled “constructors”Service
Section titled “Service”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 serviceconst Database = Context.Service<{ query: (sql: string) => string}>("Database")
// Create a service classclass Config extends Context.Service< Config, { port: number }>()("Config") {}
// Use the services to create contextsconst db = Context.make(Database, { query: (sql) => `Result: ${sql}`})const config = Context.make(Config, { port: 8080 })See
Referencefor service keys with default values
Signature
declare 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 }}Since v4.0.0
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)Signature
declare const empty: () => Context<never>Since v2.0.0
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 })Signature
declare const make: <I, S>(key: Key<I, S>, service: Types.NoInfer<S>) => Context<I>Since v2.0.0
makeUnsafe
Section titled “makeUnsafe”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)Signature
declare const makeUnsafe: <Services = never>(mapUnsafe: ReadonlyMap<string, any>) => Context<Services>Since v4.0.0
filtering
Section titled “filtering”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())See
pickfor keeping selected services
Signature
declare const omit: <S extends ReadonlyArray<Key<any, any>>>( ...keys: S) => <Services>(self: Context<Services>) => Context<Exclude<Services, Service.Identifier<S[number]>>>Since v2.0.0
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())See
omitfor removing selected services
Signature
declare const pick: <S extends ReadonlyArray<Key<any, any>>>( ...services: S) => <Services>(self: Context<Services>) => Context<Services & Service.Identifier<S[number]>>Since v2.0.0
getters
Section titled “getters”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 })See
getOptionfor optional service accessgetOrElsefor fallback values
Signature
declare 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}Since v2.0.0
getOption
Section titled “getOption”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())See
getOrElsefor returning a fallback value directly
Signature
declare 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>}Since v2.0.0
getOrElse
Section titled “getOrElse”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)) // trueconsole.log(database.query("SELECT 1")) // "fallback"See
getOptionfor returningOption.nonewhen a non-reference key is missing
Signature
declare 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}Since v3.7.0
getOrUndefined
Section titled “getOrUndefined”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
getOptionfor a reference-aware optional lookup
Signature
declare 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}Since v4.0.0
guards
Section titled “guards”isContext
Section titled “isContext”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)See
isKeyfor checking service keysisReferencefor checking references with defaults
Signature
declare const isContext: (u: unknown) => u is Context<never>Since v2.0.0
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)Signature
declare const isKey: (u: unknown) => u is Key<any, any>Since v4.0.0
isReference
Section titled “isReference”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)Signature
declare const isReference: (u: unknown) => u is Reference<any>Since v3.11.0
models
Section titled “models”Context (interface)
Section titled “Context (interface)”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 servicesconst 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}` }))Signature
export interface Context<in Services> extends Equal.Equal, Pipeable, Inspectable { readonly [TypeId]: { readonly _Services: Types.Contravariant<Services> } readonly mapUnsafe: ReadonlyMap<string, any> mutable: boolean}Since v2.0.0
Key (interface)
Section titled “Key (interface)”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.
See
Servicefor creating required service keysReferencefor creating service keys with default values
Signature
export interface Key<out Identifier, out Shape> extends Effect<Shape, never, Identifier> { readonly [ServiceTypeId]: ServiceTypeId readonly Service: Shape readonly Identifier: Identifier readonly key: string readonly stack?: string | undefined}Since v4.0.0
Reference (interface)
Section titled “Reference (interface)”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 valueconst LoggerRef: Context.Reference<{ log: (msg: string) => void }> = Context.Reference("Logger", { defaultValue: () => ({ log: (msg: string) => console.log(msg) })})
// The reference can be used without explicit provisionconst context = Context.empty()const logger = Context.get(context, LoggerRef) // Uses default valueSignature
export interface Reference<in out Shape> extends Service<never, Shape> { readonly [ReferenceTypeId]: typeof ReferenceTypeId readonly defaultValue: () => Shape [Symbol.iterator](): EffectIterator<Reference<Shape>> new (_: never): {}}Since v3.11.0
Service (interface)
Section titled “Service (interface)”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 serviceconst Database = Context.Service<{ query: (sql: string) => string }>("Database")
// The key can be used to store and retrieve servicesconst context = Context.make(Database, { query: (sql) => `Result: ${sql}` })Signature
export interface Service<in out Identifier, in out Shape> extends Key<Identifier, Shape> { of(this: void, self: Shape): Shape context(self: Shape): Context<Identifier> use<A, E, R>(f: (service: Shape) => Effect<A, E, R>): Effect<A, E, R | Identifier> useSync<A>(f: (service: Shape) => A): Effect<A, never, Identifier>}Since v4.0.0
ServiceClass (interface)
Section titled “ServiceClass (interface)”Class-style service key produced by Context.Service<Self, Shape>()("Id").
When to use
Use when declaring a service as a class so the class value can serve as the
Context key.
Details
The class itself is the Context key, and its string key identifies the
service at runtime.
See
Servicefor creating function-style keys or class-style service keys
Signature
export interface ServiceClass<in out Self, in out Identifier extends string, in out Shape> extends Service< Self, Shape> { new (_: never): ServiceClass.Shape<Identifier, Shape> readonly key: Identifier}Since v4.0.0
mutations
Section titled “mutations”mutate
Section titled “mutate”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
addfor adding or replacing a serviceaddOrOmitfor adding or removing a service from anOptionmergefor combining two contextspickfor keeping selected servicesomitfor removing selected services
Signature
declare 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>}Since v4.0.0
references
Section titled “references”Reference
Section titled “Reference”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 valueconst LoggerRef = Context.Reference("Logger", { defaultValue: () => ({ log: (msg: string) => console.log(msg) })})
// The reference provides the default value when accessed from an empty contextconst context = Context.empty()const logger = Context.get(context, LoggerRef)
// You can also override the default valueconst customContext = Context.make(LoggerRef, { log: (msg: string) => `Custom: ${msg}`})const customLogger = Context.get(customContext, LoggerRef)See
Servicefor required services without default values
Signature
declare const Reference: <Service>(key: string, options: { readonly defaultValue: () => Service }) => Reference<Service>Since v3.11.0
type IDs
Section titled “type IDs”ServiceTypeId
Section titled “ServiceTypeId”Runtime type identifier attached to Context service keys and used by
isKey to recognize them.
Signature
declare const ServiceTypeId: "~effect/Context/Service"Since v4.0.0
ServiceTypeId (type alias)
Section titled “ServiceTypeId (type alias)”String literal type used as the runtime type identifier for Context
service keys.
Signature
type ServiceTypeId = "~effect/Context/Service"Since v4.0.0
unsafe
Section titled “unsafe”getReferenceUnsafe
Section titled “getReferenceUnsafe”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"See
getUnsafefor unsafe access with any service keygetfor type-checked reference-aware accessgetOptionfor optional access to non-reference keys
Signature
declare const getReferenceUnsafe: <Services, S>(self: Context<Services>, service: Reference<S>) => SSince v4.0.0
getUnsafe
Section titled “getUnsafe”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))See
getfor type-checked service accessgetOptionfor optional service access
Signature
declare const getUnsafe: { <S, I>(service: Key<I, S>): <Services>(self: Context<Services>) => S <Services, S, I>(self: Context<Services>, services: Key<I, S>): S}Since v4.0.0
Service (namespace)
Section titled “Service (namespace)”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 keytype DatabaseService = Context.Service.Shape<typeof Database>
// Extract identifier type from a keytype DatabaseId = Context.Service.Identifier<typeof Database>Since v2.0.0
Any (type alias)
Section titled “Any (type alias)”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 typeconst services: Array<Context.Service.Any> = [ Context.Service<{ log: (msg: string) => void }>("Logger"), Context.Service<{ query: (sql: string) => string }>("Database")]Signature
type Any = Key<never, any> | Key<any, any>Since v4.0.0
Shape (type alias)
Section titled “Shape (type alias)”Extracts 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 servicetype DatabaseService = Context.Service.Shape<typeof Database>// DatabaseService is { query: (sql: string) => string }Signature
type Shape<T> = T extends Key<infer _I, infer S> ? S : neverSince v4.0.0
Identifier (type alias)
Section titled “Identifier (type alias)”Extracts 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 keytype DatabaseId = Context.Service.Identifier<typeof Database>// DatabaseId is the identifier typeSignature
type Identifier<T> = T extends Key<infer I, infer _S> ? I : neverSince v2.0.0
ServiceClass (namespace)
Section titled “ServiceClass (namespace)”Namespace containing helper types for class-style Context.Service
declarations.
Since v4.0.0
Shape (interface)
Section titled “Shape (interface)”Runtime and type-level metadata carried by a class-style service key, including its service type identifier, string key, and service shape.
Signature
export interface Shape<Identifier extends string, Service> { readonly [ServiceTypeId]: typeof ServiceTypeId readonly key: Identifier readonly Service: Service}Since v4.0.0