Optional<S, A>The most general optic — both reading and writing can fail.
When to use
Use when the focus may not exist in S and writing a new A back may also
fail, for example when the source no longer matches the expected shape. This
is the base type extended by Iso, Lens, Prism, and
Traversal.
Details
getResult(s)returnsResult.Success<A>orResult.Failure<string>.replaceResult(a, s)returnsResult.Success<S>orResult.Failure<string>.replace(a, s)returns the originalson failure (never throws).modify(f)returns the originalson failure (never throws).- All operations are pure; inputs are never mutated.
Example (Focusing on an optional record key)
import { Optic, Result } from "effect"
type Env = { [key: string]: string }
const _home = Optic.id<Env>().at("HOME")
console.log(Result.isSuccess(_home.getResult({ HOME: "/root" })))
// Output: true
console.log(Result.isFailure(_home.getResult({ PATH: "/bin" })))
// Output: true
// replace returns original on failure
console.log(_home.replace("/new", { PATH: "/bin" }))
// Output: { PATH: "/bin" }export interface interface Optional<in out S, in out A>The most general optic — both reading and writing can fail.
When to use
Use when the focus may not exist in S and writing a new A back may also
fail, for example when the source no longer matches the expected shape. This
is the base type extended by
Iso
,
Lens
,
Prism
, and
Details
getResult(s) returns Result.Success<A> or Result.Failure<string>.
replaceResult(a, s) returns Result.Success<S> or
Result.Failure<string>.
replace(a, s) returns the original s on failure (never throws).
modify(f) returns the original s on failure (never throws).
- All operations are pure; inputs are never mutated.
Example (Focusing on an optional record key)
import { Optic, Result } from "effect"
type Env = { [key: string]: string }
const _home = Optic.id<Env>().at("HOME")
console.log(Result.isSuccess(_home.getResult({ HOME: "/root" })))
// Output: true
console.log(Result.isFailure(_home.getResult({ PATH: "/bin" })))
// Output: true
// replace returns original on failure
console.log(_home.replace("/new", { PATH: "/bin" }))
// Output: { PATH: "/bin" }
Optional<in out function (type parameter) S in Optional<in out S, in out A>S, in out function (type parameter) A in Optional<in out S, in out A>A> {
readonly Optional<in out S, in out A>.node: Nodenode: type Node =
| IdentityNode
| IsoNode<any, any>
| LensNode<any, any>
| PrismNode<any, any>
| OptionalNode<any, any>
| PathNode
| CheckNode<any>
| CompositionNode
Node
/**
* Attempts to read the focus `A` from the whole `S`. Returns
* `Result.Success<A>` when the focus exists, or
* `Result.Failure<string>` with a descriptive error otherwise.
*/
readonly Optional<in out S, in out A>.getResult: (s: S) => Result.Result<A, string>Attempts to read the focus A from the whole S. Returns
Result.Success<A> when the focus exists, or
Result.Failure<string> with a descriptive error otherwise.
getResult: (s: in out Ss: function (type parameter) S in Optional<in out S, in out A>S) => import ResultResult.type Result<A, E = never> = Result.Success<A, E> | Result.Failure<A, E>A value that is either Success<A, E> or Failure<A, E>.
When to use
Use when both success and failure should remain available as data and
Option would lose failure information.
Details
- Use
succeed
/
fail
to construct
- Use
match
to fold both branches
- Use
isSuccess
/
isFailure
to narrow the type
E defaults to never, so Result<number> means a result that cannot fail.
Example (Creating and matching a Result)
import { Result } from "effect"
const success = Result.succeed(42)
const failure = Result.fail("something went wrong")
const message = Result.match(success, {
onSuccess: (value) => `Success: ${value}`,
onFailure: (error) => `Error: ${error}`
})
console.log(message)
// Output: "Success: 42"
Namespace containing type-level utilities for extracting the inner types
of a Result.
Example (Extracting inner types)
import type { Result } from "effect"
type R = Result.Result<number, string>
// number
type A = Result.Result.Success<R>
// string
type E = Result.Result.Failure<R>
Result<function (type parameter) A in Optional<in out S, in out A>A, string>
/**
* Replaces the focus in `S` with a new `A`. Returns the original `s`
* unchanged when the optic cannot focus (never throws).
*/
readonly Optional<in out S, in out A>.replace: (a: A, s: S) => SReplaces the focus in S with a new A. Returns the original s
unchanged when the optic cannot focus (never throws).
replace: (a: in out Aa: function (type parameter) A in Optional<in out S, in out A>A, s: in out Ss: function (type parameter) S in Optional<in out S, in out A>S) => function (type parameter) S in Optional<in out S, in out A>S
/**
* Like {@link replace}, but returns an explicit `Result` so callers can
* detect and handle failure.
*/
readonly Optional<in out S, in out A>.replaceResult: (a: A, s: S) => Result.Result<S, string>Like
replace
, but returns an explicit Result so callers can
detect and handle failure.
replaceResult: (a: in out Aa: function (type parameter) A in Optional<in out S, in out A>A, s: in out Ss: function (type parameter) S in Optional<in out S, in out A>S) => import ResultResult.type Result<A, E = never> = Result.Success<A, E> | Result.Failure<A, E>A value that is either Success<A, E> or Failure<A, E>.
When to use
Use when both success and failure should remain available as data and
Option would lose failure information.
Details
- Use
succeed
/
fail
to construct
- Use
match
to fold both branches
- Use
isSuccess
/
isFailure
to narrow the type
E defaults to never, so Result<number> means a result that cannot fail.
Example (Creating and matching a Result)
import { Result } from "effect"
const success = Result.succeed(42)
const failure = Result.fail("something went wrong")
const message = Result.match(success, {
onSuccess: (value) => `Success: ${value}`,
onFailure: (error) => `Error: ${error}`
})
console.log(message)
// Output: "Success: 42"
Namespace containing type-level utilities for extracting the inner types
of a Result.
Example (Extracting inner types)
import type { Result } from "effect"
type R = Result.Result<number, string>
// number
type A = Result.Result.Success<R>
// string
type E = Result.Result.Failure<R>
Result<function (type parameter) S in Optional<in out S, in out A>S, string>
/**
* Composes this optic with another. The result type is the weakest of
* the two: Iso + Iso = Iso, Lens + Prism = Optional, etc.
*
* **Example** (Composing a lens with a prism)
*
* ```ts
* import { Optic, Option } from "effect"
*
* type State = { value: Option.Option<number> }
*
* const _inner = Optic.id<State>().key("value").compose(Optic.some())
* // _inner is Optional<State, number>
* ```
*
* @see {@link id} — start a composition chain
*/
Optional<in out S, in out A>.compose<B>(this: Iso<S, A>, that: Iso<A, B>): Iso<S, B> (+3 overloads)Composes this optic with another. The result type is the weakest of
the two: Iso + Iso = Iso, Lens + Prism = Optional, etc.
Example (Composing a lens with a prism)
import { Optic, Option } from "effect"
type State = { value: Option.Option<number> }
const _inner = Optic.id<State>().key("value").compose(Optic.some())
// _inner is Optional<State, number>
compose<function (type parameter) B in Optional<in out S, in out A>.compose<B>(this: Iso<S, A>, that: Iso<A, B>): Iso<S, B>B>(this: Iso<S, A>(parameter) this: {
get: (s: S) => A;
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { <B>(this: Iso<S, A>, that: Iso<A, B>): Iso<S, B>; <B>(this: Lens<S, A>, that: Lens<A, B>): Lens<S, B>; <B>(this: Prism<S, A>, that: Prism<A, B>): Prism<S, B>; <B>(this: Optional<S, A>, that: Optional<A, B>): Optional<S, B> };
modify: (f: (a: A) => A) => (s: S) => S;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<S, Exclude<A, undefined>>; (): Optional<S, Exclude<A, undefined>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
set: (a: A) => S;
}
this: interface Iso<in out S, in out A>A lossless, reversible conversion between types S and A.
When to use
Use when you have a pair of functions that convert back and forth without losing
information (e.g. Record ↔ entries, Celsius ↔ Fahrenheit).
- You want the strongest optic that can be composed with any other.
Details
get(s) always succeeds and returns an A.
set(a) always succeeds and returns an S.
get(set(a)) === a and set(get(s)) equals s (round-trip laws).
- Extends both
Lens
and
Prism
.
Example (Converting between Celsius and Fahrenheit)
import { Optic } from "effect"
const fahrenheit = Optic.makeIso<number, number>(
(c) => c * 9 / 5 + 32,
(f) => (f - 32) * 5 / 9
)
console.log(fahrenheit.get(100))
// Output: 212
console.log(fahrenheit.set(32))
// Output: 0
Iso<function (type parameter) S in Optional<in out S, in out A>S, function (type parameter) A in Optional<in out S, in out A>A>, that: Iso<A, B>(parameter) that: {
get: (s: S) => A;
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { (this: Iso<A, B>, that: Iso<B, B>): Iso<A, B>; (this: Lens<A, B>, that: Lens<B, B>): Lens<A, B>; (this: Prism<A, B>, that: Prism<B, B>): Prism<A, B>; (this: Optional<A, B>, that: Optional<B, B>): Optional<A, B> };
modify: (f: (a: B) => B) => (s: A) => A;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<A, Exclude<B, undefined>>; (): Optional<A, Exclude<B, undefined>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
set: (a: A) => S;
}
that: interface Iso<in out S, in out A>A lossless, reversible conversion between types S and A.
When to use
Use when you have a pair of functions that convert back and forth without losing
information (e.g. Record ↔ entries, Celsius ↔ Fahrenheit).
- You want the strongest optic that can be composed with any other.
Details
get(s) always succeeds and returns an A.
set(a) always succeeds and returns an S.
get(set(a)) === a and set(get(s)) equals s (round-trip laws).
- Extends both
Lens
and
Prism
.
Example (Converting between Celsius and Fahrenheit)
import { Optic } from "effect"
const fahrenheit = Optic.makeIso<number, number>(
(c) => c * 9 / 5 + 32,
(f) => (f - 32) * 5 / 9
)
console.log(fahrenheit.get(100))
// Output: 212
console.log(fahrenheit.set(32))
// Output: 0
Iso<function (type parameter) A in Optional<in out S, in out A>A, function (type parameter) B in Optional<in out S, in out A>.compose<B>(this: Iso<S, A>, that: Iso<A, B>): Iso<S, B>B>): interface Iso<in out S, in out A>A lossless, reversible conversion between types S and A.
When to use
Use when you have a pair of functions that convert back and forth without losing
information (e.g. Record ↔ entries, Celsius ↔ Fahrenheit).
- You want the strongest optic that can be composed with any other.
Details
get(s) always succeeds and returns an A.
set(a) always succeeds and returns an S.
get(set(a)) === a and set(get(s)) equals s (round-trip laws).
- Extends both
Lens
and
Prism
.
Example (Converting between Celsius and Fahrenheit)
import { Optic } from "effect"
const fahrenheit = Optic.makeIso<number, number>(
(c) => c * 9 / 5 + 32,
(f) => (f - 32) * 5 / 9
)
console.log(fahrenheit.get(100))
// Output: 212
console.log(fahrenheit.set(32))
// Output: 0
Iso<function (type parameter) S in Optional<in out S, in out A>S, function (type parameter) B in Optional<in out S, in out A>.compose<B>(this: Iso<S, A>, that: Iso<A, B>): Iso<S, B>B>
Optional<in out S, in out A>.compose<B>(this: Lens<S, A>, that: Lens<A, B>): Lens<S, B> (+3 overloads)Composes this optic with another. The result type is the weakest of
the two: Iso + Iso = Iso, Lens + Prism = Optional, etc.
Example (Composing a lens with a prism)
import { Optic, Option } from "effect"
type State = { value: Option.Option<number> }
const _inner = Optic.id<State>().key("value").compose(Optic.some())
// _inner is Optional<State, number>
compose<function (type parameter) B in Optional<in out S, in out A>.compose<B>(this: Lens<S, A>, that: Lens<A, B>): Lens<S, B>B>(this: Lens<S, A>(parameter) this: {
get: (s: S) => A;
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { <B>(this: Iso<S, A>, that: Iso<A, B>): Iso<S, B>; <B>(this: Lens<S, A>, that: Lens<A, B>): Lens<S, B>; <B>(this: Prism<S, A>, that: Prism<A, B>): Prism<S, B>; <B>(this: Optional<S, A>, that: Optional<A, B>): Optional<S, B> };
modify: (f: (a: A) => A) => (s: S) => S;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<S, Exclude<A, undefined>>; (): Optional<S, Exclude<A, undefined>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
}
this: interface Lens<in out S, in out A>Focuses on exactly one part A inside a whole S.
When to use
Use when you always have a value to read and need the original S to produce
the updated whole, unlike Iso.
Details
get(s) always succeeds and returns A.
replace(a, s) returns a new S with the focused part replaced.
- Extends
Optional
.
- Composing a Lens with a
Prism
or
Optional
produces an
Optional
.
Example (Focusing on a struct field)
import { Optic } from "effect"
type Person = { readonly name: string; readonly age: number }
const _name = Optic.id<Person>().key("name")
console.log(_name.get({ name: "Alice", age: 30 }))
// Output: "Alice"
Lens<function (type parameter) S in Optional<in out S, in out A>S, function (type parameter) A in Optional<in out S, in out A>A>, that: Lens<A, B>(parameter) that: {
get: (s: S) => A;
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { (this: Iso<A, B>, that: Iso<B, B>): Iso<A, B>; (this: Lens<A, B>, that: Lens<B, B>): Lens<A, B>; (this: Prism<A, B>, that: Prism<B, B>): Prism<A, B>; (this: Optional<A, B>, that: Optional<B, B>): Optional<A, B> };
modify: (f: (a: B) => B) => (s: A) => A;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<A, Exclude<B, undefined>>; (): Optional<A, Exclude<B, undefined>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
}
that: interface Lens<in out S, in out A>Focuses on exactly one part A inside a whole S.
When to use
Use when you always have a value to read and need the original S to produce
the updated whole, unlike Iso.
Details
get(s) always succeeds and returns A.
replace(a, s) returns a new S with the focused part replaced.
- Extends
Optional
.
- Composing a Lens with a
Prism
or
Optional
produces an
Optional
.
Example (Focusing on a struct field)
import { Optic } from "effect"
type Person = { readonly name: string; readonly age: number }
const _name = Optic.id<Person>().key("name")
console.log(_name.get({ name: "Alice", age: 30 }))
// Output: "Alice"
Lens<function (type parameter) A in Optional<in out S, in out A>A, function (type parameter) B in Optional<in out S, in out A>.compose<B>(this: Lens<S, A>, that: Lens<A, B>): Lens<S, B>B>): interface Lens<in out S, in out A>Focuses on exactly one part A inside a whole S.
When to use
Use when you always have a value to read and need the original S to produce
the updated whole, unlike Iso.
Details
get(s) always succeeds and returns A.
replace(a, s) returns a new S with the focused part replaced.
- Extends
Optional
.
- Composing a Lens with a
Prism
or
Optional
produces an
Optional
.
Example (Focusing on a struct field)
import { Optic } from "effect"
type Person = { readonly name: string; readonly age: number }
const _name = Optic.id<Person>().key("name")
console.log(_name.get({ name: "Alice", age: 30 }))
// Output: "Alice"
Lens<function (type parameter) S in Optional<in out S, in out A>S, function (type parameter) B in Optional<in out S, in out A>.compose<B>(this: Lens<S, A>, that: Lens<A, B>): Lens<S, B>B>
Optional<in out S, in out A>.compose<B>(this: Prism<S, A>, that: Prism<A, B>): Prism<S, B> (+3 overloads)Composes this optic with another. The result type is the weakest of
the two: Iso + Iso = Iso, Lens + Prism = Optional, etc.
Example (Composing a lens with a prism)
import { Optic, Option } from "effect"
type State = { value: Option.Option<number> }
const _inner = Optic.id<State>().key("value").compose(Optic.some())
// _inner is Optional<State, number>
compose<function (type parameter) B in Optional<in out S, in out A>.compose<B>(this: Prism<S, A>, that: Prism<A, B>): Prism<S, B>B>(this: Prism<S, A>(parameter) this: {
set: (a: A) => S;
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { <B>(this: Iso<S, A>, that: Iso<A, B>): Iso<S, B>; <B>(this: Lens<S, A>, that: Lens<A, B>): Lens<S, B>; <B>(this: Prism<S, A>, that: Prism<A, B>): Prism<S, B>; <B>(this: Optional<S, A>, that: Optional<A, B>): Optional<S, B> };
modify: (f: (a: A) => A) => (s: S) => S;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<S, Exclude<A, undefined>>; (): Optional<S, Exclude<A, undefined>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
}
this: interface Prism<in out S, in out A>Focuses on a part A of S that may not be present (e.g. a union
variant or a validated subset).
When to use
Use when the focus is conditional — reading can fail (wrong variant, failed
validation).
- Building a new
S from A does not require the original S.
Details
getResult(s) returns Result.Success<A> when the focus matches, or
Result.Failure<string> with an error message.
set(a) always succeeds and returns a new S.
- Extends
Optional
.
- Composing two Prisms produces a Prism; composing a Prism with a
Example (Narrowing a tagged union)
import { Optic, Result } from "effect"
type Shape =
| { readonly _tag: "Circle"; readonly radius: number }
| { readonly _tag: "Rect"; readonly width: number }
const _circle = Optic.id<Shape>().tag("Circle")
console.log(Result.isSuccess(_circle.getResult({ _tag: "Circle", radius: 5 })))
// Output: true
console.log(Result.isFailure(_circle.getResult({ _tag: "Rect", width: 10 })))
// Output: true
Prism<function (type parameter) S in Optional<in out S, in out A>S, function (type parameter) A in Optional<in out S, in out A>A>, that: Prism<A, B>(parameter) that: {
set: (a: A) => S;
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { (this: Iso<A, B>, that: Iso<B, B>): Iso<A, B>; (this: Lens<A, B>, that: Lens<B, B>): Lens<A, B>; (this: Prism<A, B>, that: Prism<B, B>): Prism<A, B>; (this: Optional<A, B>, that: Optional<B, B>): Optional<A, B> };
modify: (f: (a: B) => B) => (s: A) => A;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<A, Exclude<B, undefined>>; (): Optional<A, Exclude<B, undefined>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
}
that: interface Prism<in out S, in out A>Focuses on a part A of S that may not be present (e.g. a union
variant or a validated subset).
When to use
Use when the focus is conditional — reading can fail (wrong variant, failed
validation).
- Building a new
S from A does not require the original S.
Details
getResult(s) returns Result.Success<A> when the focus matches, or
Result.Failure<string> with an error message.
set(a) always succeeds and returns a new S.
- Extends
Optional
.
- Composing two Prisms produces a Prism; composing a Prism with a
Example (Narrowing a tagged union)
import { Optic, Result } from "effect"
type Shape =
| { readonly _tag: "Circle"; readonly radius: number }
| { readonly _tag: "Rect"; readonly width: number }
const _circle = Optic.id<Shape>().tag("Circle")
console.log(Result.isSuccess(_circle.getResult({ _tag: "Circle", radius: 5 })))
// Output: true
console.log(Result.isFailure(_circle.getResult({ _tag: "Rect", width: 10 })))
// Output: true
Prism<function (type parameter) A in Optional<in out S, in out A>A, function (type parameter) B in Optional<in out S, in out A>.compose<B>(this: Prism<S, A>, that: Prism<A, B>): Prism<S, B>B>): interface Prism<in out S, in out A>Focuses on a part A of S that may not be present (e.g. a union
variant or a validated subset).
When to use
Use when the focus is conditional — reading can fail (wrong variant, failed
validation).
- Building a new
S from A does not require the original S.
Details
getResult(s) returns Result.Success<A> when the focus matches, or
Result.Failure<string> with an error message.
set(a) always succeeds and returns a new S.
- Extends
Optional
.
- Composing two Prisms produces a Prism; composing a Prism with a
Example (Narrowing a tagged union)
import { Optic, Result } from "effect"
type Shape =
| { readonly _tag: "Circle"; readonly radius: number }
| { readonly _tag: "Rect"; readonly width: number }
const _circle = Optic.id<Shape>().tag("Circle")
console.log(Result.isSuccess(_circle.getResult({ _tag: "Circle", radius: 5 })))
// Output: true
console.log(Result.isFailure(_circle.getResult({ _tag: "Rect", width: 10 })))
// Output: true
Prism<function (type parameter) S in Optional<in out S, in out A>S, function (type parameter) B in Optional<in out S, in out A>.compose<B>(this: Prism<S, A>, that: Prism<A, B>): Prism<S, B>B>
Optional<in out S, in out A>.compose<B>(this: Optional<S, A>, that: Optional<A, B>): Optional<S, B> (+3 overloads)Composes this optic with another. The result type is the weakest of
the two: Iso + Iso = Iso, Lens + Prism = Optional, etc.
Example (Composing a lens with a prism)
import { Optic, Option } from "effect"
type State = { value: Option.Option<number> }
const _inner = Optic.id<State>().key("value").compose(Optic.some())
// _inner is Optional<State, number>
compose<function (type parameter) B in Optional<in out S, in out A>.compose<B>(this: Optional<S, A>, that: Optional<A, B>): Optional<S, B>B>(this: Optional<S, A>(parameter) this: {
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { <B>(this: Iso<S, A>, that: Iso<A, B>): Iso<S, B>; <B>(this: Lens<S, A>, that: Lens<A, B>): Lens<S, B>; <B>(this: Prism<S, A>, that: Prism<A, B>): Prism<S, B>; <B>(this: Optional<S, A>, that: Optional<A, B>): Optional<S, B> };
modify: (f: (a: A) => A) => (s: S) => S;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<S, Exclude<A, undefined>>; (): Optional<S, Exclude<A, undefined>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
}
this: interface Optional<in out S, in out A>The most general optic — both reading and writing can fail.
When to use
Use when the focus may not exist in S and writing a new A back may also
fail, for example when the source no longer matches the expected shape. This
is the base type extended by
Iso
,
Lens
,
Prism
, and
Details
getResult(s) returns Result.Success<A> or Result.Failure<string>.
replaceResult(a, s) returns Result.Success<S> or
Result.Failure<string>.
replace(a, s) returns the original s on failure (never throws).
modify(f) returns the original s on failure (never throws).
- All operations are pure; inputs are never mutated.
Example (Focusing on an optional record key)
import { Optic, Result } from "effect"
type Env = { [key: string]: string }
const _home = Optic.id<Env>().at("HOME")
console.log(Result.isSuccess(_home.getResult({ HOME: "/root" })))
// Output: true
console.log(Result.isFailure(_home.getResult({ PATH: "/bin" })))
// Output: true
// replace returns original on failure
console.log(_home.replace("/new", { PATH: "/bin" }))
// Output: { PATH: "/bin" }
Optional<function (type parameter) S in Optional<in out S, in out A>S, function (type parameter) A in Optional<in out S, in out A>A>, that: Optional<A, B>(parameter) that: {
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { (this: Iso<A, B>, that: Iso<B, B>): Iso<A, B>; (this: Lens<A, B>, that: Lens<B, B>): Lens<A, B>; (this: Prism<A, B>, that: Prism<B, B>): Prism<A, B>; (this: Optional<A, B>, that: Optional<B, B>): Optional<A, B> };
modify: (f: (a: B) => B) => (s: A) => A;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<A, Exclude<B, undefined>>; (): Optional<A, Exclude<B, undefined>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
}
that: interface Optional<in out S, in out A>The most general optic — both reading and writing can fail.
When to use
Use when the focus may not exist in S and writing a new A back may also
fail, for example when the source no longer matches the expected shape. This
is the base type extended by
Iso
,
Lens
,
Prism
, and
Details
getResult(s) returns Result.Success<A> or Result.Failure<string>.
replaceResult(a, s) returns Result.Success<S> or
Result.Failure<string>.
replace(a, s) returns the original s on failure (never throws).
modify(f) returns the original s on failure (never throws).
- All operations are pure; inputs are never mutated.
Example (Focusing on an optional record key)
import { Optic, Result } from "effect"
type Env = { [key: string]: string }
const _home = Optic.id<Env>().at("HOME")
console.log(Result.isSuccess(_home.getResult({ HOME: "/root" })))
// Output: true
console.log(Result.isFailure(_home.getResult({ PATH: "/bin" })))
// Output: true
// replace returns original on failure
console.log(_home.replace("/new", { PATH: "/bin" }))
// Output: { PATH: "/bin" }
Optional<function (type parameter) A in Optional<in out S, in out A>A, function (type parameter) B in Optional<in out S, in out A>.compose<B>(this: Optional<S, A>, that: Optional<A, B>): Optional<S, B>B>): interface Optional<in out S, in out A>The most general optic — both reading and writing can fail.
When to use
Use when the focus may not exist in S and writing a new A back may also
fail, for example when the source no longer matches the expected shape. This
is the base type extended by
Iso
,
Lens
,
Prism
, and
Details
getResult(s) returns Result.Success<A> or Result.Failure<string>.
replaceResult(a, s) returns Result.Success<S> or
Result.Failure<string>.
replace(a, s) returns the original s on failure (never throws).
modify(f) returns the original s on failure (never throws).
- All operations are pure; inputs are never mutated.
Example (Focusing on an optional record key)
import { Optic, Result } from "effect"
type Env = { [key: string]: string }
const _home = Optic.id<Env>().at("HOME")
console.log(Result.isSuccess(_home.getResult({ HOME: "/root" })))
// Output: true
console.log(Result.isFailure(_home.getResult({ PATH: "/bin" })))
// Output: true
// replace returns original on failure
console.log(_home.replace("/new", { PATH: "/bin" }))
// Output: { PATH: "/bin" }
Optional<function (type parameter) S in Optional<in out S, in out A>S, function (type parameter) B in Optional<in out S, in out A>.compose<B>(this: Optional<S, A>, that: Optional<A, B>): Optional<S, B>B>
/**
* Returns a function `(s: S) => S` that applies `f` to the focused value.
* If the optic cannot focus, the original `s` is returned unchanged.
*
* **Example** (Incrementing a nested field)
*
* ```ts
* import { Optic } from "effect"
*
* type S = { readonly a: { readonly b: number } }
* const _b = Optic.id<S>().key("a").key("b")
*
* const inc = _b.modify((n) => n + 1)
* console.log(inc({ a: { b: 1 } }))
* // Output: { a: { b: 2 } }
* ```
*/
Optional<in out S, in out A>.modify(f: (a: A) => A): (s: S) => SReturns a function (s: S) => S that applies f to the focused value.
If the optic cannot focus, the original s is returned unchanged.
Example (Incrementing a nested field)
import { Optic } from "effect"
type S = { readonly a: { readonly b: number } }
const _b = Optic.id<S>().key("a").key("b")
const inc = _b.modify((n) => n + 1)
console.log(inc({ a: { b: 1 } }))
// Output: { a: { b: 2 } }
modify(f: (a: A) => Af: (a: in out Aa: function (type parameter) A in Optional<in out S, in out A>A) => function (type parameter) A in Optional<in out S, in out A>A): (s: in out Ss: function (type parameter) S in Optional<in out S, in out A>S) => function (type parameter) S in Optional<in out S, in out A>S
/**
* Focuses on a property of the current struct/tuple focus.
*
* **Details**
*
* - On a {@link Lens}, returns a Lens.
* - On an {@link Optional}, returns an Optional.
* - Does **not** work on union types (compile error).
*
* **Example** (Drilling into nested structs)
*
* ```ts
* import { Optic } from "effect"
*
* type S = { readonly a: { readonly b: number } }
* const _b = Optic.id<S>().key("a").key("b")
*
* console.log(_b.get({ a: { b: 42 } }))
* // Output: 42
* ```
*/
Optional<in out S, in out A>.key<S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `key` on a union type">): Lens<S, A[Key]> (+1 overload)Focuses on a property of the current struct/tuple focus.
Details
- On a
Lens
, returns a Lens.
- On an
Optional
, returns an Optional.
- Does not work on union types (compile error).
Example (Drilling into nested structs)
import { Optic } from "effect"
type S = { readonly a: { readonly b: number } }
const _b = Optic.id<S>().key("a").key("b")
console.log(_b.get({ a: { b: 42 } }))
// Output: 42
key<function (type parameter) S in Optional<in out S, in out A>.key<S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `key` on a union type">): Lens<S, A[Key]>S, function (type parameter) A in Optional<in out S, in out A>.key<S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `key` on a union type">): Lens<S, A[Key]>A extends object, function (type parameter) Key in Optional<in out S, in out A>.key<S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `key` on a union type">): Lens<S, A[Key]>Key extends keyof function (type parameter) A in Optional<in out S, in out A>.key<S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `key` on a union type">): Lens<S, A[Key]>A>(
this: Lens<S, A>(parameter) this: {
get: (s: S) => A;
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { (this: Iso<S, A>, that: Iso<A, B>): Iso<S, B>; (this: Lens<S, A>, that: Lens<A, B>): Lens<S, B>; (this: Prism<S, A>, that: Prism<A, B>): Prism<S, B>; (this: Optional<S, A>, that: Optional<A, B>): Optional<S, B> };
modify: (f: (a: A) => A) => (s: S) => S;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<S, Exclude<A, undefined>>; (): Optional<S, Exclude<A, undefined>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
}
this: interface Lens<in out S, in out A>Focuses on exactly one part A inside a whole S.
When to use
Use when you always have a value to read and need the original S to produce
the updated whole, unlike Iso.
Details
get(s) always succeeds and returns A.
replace(a, s) returns a new S with the focused part replaced.
- Extends
Optional
.
- Composing a Lens with a
Prism
or
Optional
produces an
Optional
.
Example (Focusing on a struct field)
import { Optic } from "effect"
type Person = { readonly name: string; readonly age: number }
const _name = Optic.id<Person>().key("name")
console.log(_name.get({ name: "Alice", age: 30 }))
// Output: "Alice"
Lens<function (type parameter) S in Optional<in out S, in out A>.key<S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `key` on a union type">): Lens<S, A[Key]>S, function (type parameter) A in Optional<in out S, in out A>.key<S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `key` on a union type">): Lens<S, A[Key]>A>,
key: Key extends keyof Akey: function (type parameter) Key in Optional<in out S, in out A>.key<S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `key` on a union type">): Lens<S, A[Key]>Key,
..._err: ForbidUnion<
A,
"cannot use `key` on a union type"
>
_err: type ForbidUnion<
A,
Message extends string
> = IsUnion<A> extends true ? [Message] : []
ForbidUnion<function (type parameter) A in Optional<in out S, in out A>.key<S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `key` on a union type">): Lens<S, A[Key]>A, "cannot use `key` on a union type">
): interface Lens<in out S, in out A>Focuses on exactly one part A inside a whole S.
When to use
Use when you always have a value to read and need the original S to produce
the updated whole, unlike Iso.
Details
get(s) always succeeds and returns A.
replace(a, s) returns a new S with the focused part replaced.
- Extends
Optional
.
- Composing a Lens with a
Prism
or
Optional
produces an
Optional
.
Example (Focusing on a struct field)
import { Optic } from "effect"
type Person = { readonly name: string; readonly age: number }
const _name = Optic.id<Person>().key("name")
console.log(_name.get({ name: "Alice", age: 30 }))
// Output: "Alice"
Lens<function (type parameter) S in Optional<in out S, in out A>.key<S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `key` on a union type">): Lens<S, A[Key]>S, function (type parameter) A in Optional<in out S, in out A>.key<S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `key` on a union type">): Lens<S, A[Key]>A[function (type parameter) Key in Optional<in out S, in out A>.key<S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `key` on a union type">): Lens<S, A[Key]>Key]>
Optional<in out S, in out A>.key<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `key` on a union type">): Optional<S, A[Key]> (+1 overload)Focuses on a property of the current struct/tuple focus.
Details
- On a
Lens
, returns a Lens.
- On an
Optional
, returns an Optional.
- Does not work on union types (compile error).
Example (Drilling into nested structs)
import { Optic } from "effect"
type S = { readonly a: { readonly b: number } }
const _b = Optic.id<S>().key("a").key("b")
console.log(_b.get({ a: { b: 42 } }))
// Output: 42
key<function (type parameter) S in Optional<in out S, in out A>.key<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `key` on a union type">): Optional<S, A[Key]>S, function (type parameter) A in Optional<in out S, in out A>.key<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `key` on a union type">): Optional<S, A[Key]>A extends object, function (type parameter) Key in Optional<in out S, in out A>.key<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `key` on a union type">): Optional<S, A[Key]>Key extends keyof function (type parameter) A in Optional<in out S, in out A>.key<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `key` on a union type">): Optional<S, A[Key]>A>(
this: Optional<S, A>(parameter) this: {
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { (this: Iso<S, A>, that: Iso<A, B>): Iso<S, B>; (this: Lens<S, A>, that: Lens<A, B>): Lens<S, B>; (this: Prism<S, A>, that: Prism<A, B>): Prism<S, B>; (this: Optional<S, A>, that: Optional<A, B>): Optional<S, B> };
modify: (f: (a: A) => A) => (s: S) => S;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<S, Exclude<A, undefined>>; (): Optional<S, Exclude<A, undefined>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
}
this: interface Optional<in out S, in out A>The most general optic — both reading and writing can fail.
When to use
Use when the focus may not exist in S and writing a new A back may also
fail, for example when the source no longer matches the expected shape. This
is the base type extended by
Iso
,
Lens
,
Prism
, and
Details
getResult(s) returns Result.Success<A> or Result.Failure<string>.
replaceResult(a, s) returns Result.Success<S> or
Result.Failure<string>.
replace(a, s) returns the original s on failure (never throws).
modify(f) returns the original s on failure (never throws).
- All operations are pure; inputs are never mutated.
Example (Focusing on an optional record key)
import { Optic, Result } from "effect"
type Env = { [key: string]: string }
const _home = Optic.id<Env>().at("HOME")
console.log(Result.isSuccess(_home.getResult({ HOME: "/root" })))
// Output: true
console.log(Result.isFailure(_home.getResult({ PATH: "/bin" })))
// Output: true
// replace returns original on failure
console.log(_home.replace("/new", { PATH: "/bin" }))
// Output: { PATH: "/bin" }
Optional<function (type parameter) S in Optional<in out S, in out A>.key<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `key` on a union type">): Optional<S, A[Key]>S, function (type parameter) A in Optional<in out S, in out A>.key<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `key` on a union type">): Optional<S, A[Key]>A>,
key: Key extends keyof Akey: function (type parameter) Key in Optional<in out S, in out A>.key<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `key` on a union type">): Optional<S, A[Key]>Key,
..._err: ForbidUnion<
A,
"cannot use `key` on a union type"
>
_err: type ForbidUnion<
A,
Message extends string
> = IsUnion<A> extends true ? [Message] : []
ForbidUnion<function (type parameter) A in Optional<in out S, in out A>.key<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `key` on a union type">): Optional<S, A[Key]>A, "cannot use `key` on a union type">
): interface Optional<in out S, in out A>The most general optic — both reading and writing can fail.
When to use
Use when the focus may not exist in S and writing a new A back may also
fail, for example when the source no longer matches the expected shape. This
is the base type extended by
Iso
,
Lens
,
Prism
, and
Details
getResult(s) returns Result.Success<A> or Result.Failure<string>.
replaceResult(a, s) returns Result.Success<S> or
Result.Failure<string>.
replace(a, s) returns the original s on failure (never throws).
modify(f) returns the original s on failure (never throws).
- All operations are pure; inputs are never mutated.
Example (Focusing on an optional record key)
import { Optic, Result } from "effect"
type Env = { [key: string]: string }
const _home = Optic.id<Env>().at("HOME")
console.log(Result.isSuccess(_home.getResult({ HOME: "/root" })))
// Output: true
console.log(Result.isFailure(_home.getResult({ PATH: "/bin" })))
// Output: true
// replace returns original on failure
console.log(_home.replace("/new", { PATH: "/bin" }))
// Output: { PATH: "/bin" }
Optional<function (type parameter) S in Optional<in out S, in out A>.key<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `key` on a union type">): Optional<S, A[Key]>S, function (type parameter) A in Optional<in out S, in out A>.key<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `key` on a union type">): Optional<S, A[Key]>A[function (type parameter) Key in Optional<in out S, in out A>.key<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `key` on a union type">): Optional<S, A[Key]>Key]>
/**
* Focuses on a key where setting `undefined` **removes** the key from the
* struct (or splices the element from an array/tuple).
*
* **Details**
*
* - The focus type becomes `A[Key] | undefined`.
* - Does **not** work on union types (compile error).
*
* **Example** (Deleting an optional key)
*
* ```ts
* import { Optic } from "effect"
*
* type S = { readonly a?: number }
* const _a = Optic.id<S>().optionalKey("a")
*
* console.log(_a.replace(undefined, { a: 1 }))
* // Output: {}
*
* console.log(_a.replace(2, {}))
* // Output: { a: 2 }
* ```
*/
Optional<in out S, in out A>.optionalKey<S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `optionalKey` on a union type">): Lens<S, A[Key] | undefined> (+1 overload)Focuses on a key where setting undefined removes the key from the
struct (or splices the element from an array/tuple).
Details
- The focus type becomes
A[Key] | undefined.
- Does not work on union types (compile error).
Example (Deleting an optional key)
import { Optic } from "effect"
type S = { readonly a?: number }
const _a = Optic.id<S>().optionalKey("a")
console.log(_a.replace(undefined, { a: 1 }))
// Output: {}
console.log(_a.replace(2, {}))
// Output: { a: 2 }
optionalKey<function (type parameter) S in Optional<in out S, in out A>.optionalKey<S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `optionalKey` on a union type">): Lens<S, A[Key] | undefined>S, function (type parameter) A in Optional<in out S, in out A>.optionalKey<S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `optionalKey` on a union type">): Lens<S, A[Key] | undefined>A extends object, function (type parameter) Key in Optional<in out S, in out A>.optionalKey<S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `optionalKey` on a union type">): Lens<S, A[Key] | undefined>Key extends keyof function (type parameter) A in Optional<in out S, in out A>.optionalKey<S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `optionalKey` on a union type">): Lens<S, A[Key] | undefined>A>(
this: Lens<S, A>(parameter) this: {
get: (s: S) => A;
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { (this: Iso<S, A>, that: Iso<A, B>): Iso<S, B>; (this: Lens<S, A>, that: Lens<A, B>): Lens<S, B>; (this: Prism<S, A>, that: Prism<A, B>): Prism<S, B>; (this: Optional<S, A>, that: Optional<A, B>): Optional<S, B> };
modify: (f: (a: A) => A) => (s: S) => S;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<S, Exclude<A, undefined>>; (): Optional<S, Exclude<A, undefined>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
}
this: interface Lens<in out S, in out A>Focuses on exactly one part A inside a whole S.
When to use
Use when you always have a value to read and need the original S to produce
the updated whole, unlike Iso.
Details
get(s) always succeeds and returns A.
replace(a, s) returns a new S with the focused part replaced.
- Extends
Optional
.
- Composing a Lens with a
Prism
or
Optional
produces an
Optional
.
Example (Focusing on a struct field)
import { Optic } from "effect"
type Person = { readonly name: string; readonly age: number }
const _name = Optic.id<Person>().key("name")
console.log(_name.get({ name: "Alice", age: 30 }))
// Output: "Alice"
Lens<function (type parameter) S in Optional<in out S, in out A>.optionalKey<S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `optionalKey` on a union type">): Lens<S, A[Key] | undefined>S, function (type parameter) A in Optional<in out S, in out A>.optionalKey<S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `optionalKey` on a union type">): Lens<S, A[Key] | undefined>A>,
key: Key extends keyof Akey: function (type parameter) Key in Optional<in out S, in out A>.optionalKey<S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `optionalKey` on a union type">): Lens<S, A[Key] | undefined>Key,
..._err: ForbidUnion<
A,
"cannot use `optionalKey` on a union type"
>
_err: type ForbidUnion<
A,
Message extends string
> = IsUnion<A> extends true ? [Message] : []
ForbidUnion<function (type parameter) A in Optional<in out S, in out A>.optionalKey<S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `optionalKey` on a union type">): Lens<S, A[Key] | undefined>A, "cannot use `optionalKey` on a union type">
): interface Lens<in out S, in out A>Focuses on exactly one part A inside a whole S.
When to use
Use when you always have a value to read and need the original S to produce
the updated whole, unlike Iso.
Details
get(s) always succeeds and returns A.
replace(a, s) returns a new S with the focused part replaced.
- Extends
Optional
.
- Composing a Lens with a
Prism
or
Optional
produces an
Optional
.
Example (Focusing on a struct field)
import { Optic } from "effect"
type Person = { readonly name: string; readonly age: number }
const _name = Optic.id<Person>().key("name")
console.log(_name.get({ name: "Alice", age: 30 }))
// Output: "Alice"
Lens<function (type parameter) S in Optional<in out S, in out A>.optionalKey<S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `optionalKey` on a union type">): Lens<S, A[Key] | undefined>S, function (type parameter) A in Optional<in out S, in out A>.optionalKey<S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `optionalKey` on a union type">): Lens<S, A[Key] | undefined>A[function (type parameter) Key in Optional<in out S, in out A>.optionalKey<S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `optionalKey` on a union type">): Lens<S, A[Key] | undefined>Key] | undefined>
Optional<in out S, in out A>.optionalKey<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `optionalKey` on a union type">): Optional<S, A[Key] | undefined> (+1 overload)Focuses on a key where setting undefined removes the key from the
struct (or splices the element from an array/tuple).
Details
- The focus type becomes
A[Key] | undefined.
- Does not work on union types (compile error).
Example (Deleting an optional key)
import { Optic } from "effect"
type S = { readonly a?: number }
const _a = Optic.id<S>().optionalKey("a")
console.log(_a.replace(undefined, { a: 1 }))
// Output: {}
console.log(_a.replace(2, {}))
// Output: { a: 2 }
optionalKey<function (type parameter) S in Optional<in out S, in out A>.optionalKey<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `optionalKey` on a union type">): Optional<S, A[Key] | undefined>S, function (type parameter) A in Optional<in out S, in out A>.optionalKey<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `optionalKey` on a union type">): Optional<S, A[Key] | undefined>A extends object, function (type parameter) Key in Optional<in out S, in out A>.optionalKey<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `optionalKey` on a union type">): Optional<S, A[Key] | undefined>Key extends keyof function (type parameter) A in Optional<in out S, in out A>.optionalKey<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `optionalKey` on a union type">): Optional<S, A[Key] | undefined>A>(
this: Optional<S, A>(parameter) this: {
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { (this: Iso<S, A>, that: Iso<A, B>): Iso<S, B>; (this: Lens<S, A>, that: Lens<A, B>): Lens<S, B>; (this: Prism<S, A>, that: Prism<A, B>): Prism<S, B>; (this: Optional<S, A>, that: Optional<A, B>): Optional<S, B> };
modify: (f: (a: A) => A) => (s: S) => S;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<S, Exclude<A, undefined>>; (): Optional<S, Exclude<A, undefined>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
}
this: interface Optional<in out S, in out A>The most general optic — both reading and writing can fail.
When to use
Use when the focus may not exist in S and writing a new A back may also
fail, for example when the source no longer matches the expected shape. This
is the base type extended by
Iso
,
Lens
,
Prism
, and
Details
getResult(s) returns Result.Success<A> or Result.Failure<string>.
replaceResult(a, s) returns Result.Success<S> or
Result.Failure<string>.
replace(a, s) returns the original s on failure (never throws).
modify(f) returns the original s on failure (never throws).
- All operations are pure; inputs are never mutated.
Example (Focusing on an optional record key)
import { Optic, Result } from "effect"
type Env = { [key: string]: string }
const _home = Optic.id<Env>().at("HOME")
console.log(Result.isSuccess(_home.getResult({ HOME: "/root" })))
// Output: true
console.log(Result.isFailure(_home.getResult({ PATH: "/bin" })))
// Output: true
// replace returns original on failure
console.log(_home.replace("/new", { PATH: "/bin" }))
// Output: { PATH: "/bin" }
Optional<function (type parameter) S in Optional<in out S, in out A>.optionalKey<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `optionalKey` on a union type">): Optional<S, A[Key] | undefined>S, function (type parameter) A in Optional<in out S, in out A>.optionalKey<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `optionalKey` on a union type">): Optional<S, A[Key] | undefined>A>,
key: Key extends keyof Akey: function (type parameter) Key in Optional<in out S, in out A>.optionalKey<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `optionalKey` on a union type">): Optional<S, A[Key] | undefined>Key,
..._err: ForbidUnion<
A,
"cannot use `optionalKey` on a union type"
>
_err: type ForbidUnion<
A,
Message extends string
> = IsUnion<A> extends true ? [Message] : []
ForbidUnion<function (type parameter) A in Optional<in out S, in out A>.optionalKey<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `optionalKey` on a union type">): Optional<S, A[Key] | undefined>A, "cannot use `optionalKey` on a union type">
): interface Optional<in out S, in out A>The most general optic — both reading and writing can fail.
When to use
Use when the focus may not exist in S and writing a new A back may also
fail, for example when the source no longer matches the expected shape. This
is the base type extended by
Iso
,
Lens
,
Prism
, and
Details
getResult(s) returns Result.Success<A> or Result.Failure<string>.
replaceResult(a, s) returns Result.Success<S> or
Result.Failure<string>.
replace(a, s) returns the original s on failure (never throws).
modify(f) returns the original s on failure (never throws).
- All operations are pure; inputs are never mutated.
Example (Focusing on an optional record key)
import { Optic, Result } from "effect"
type Env = { [key: string]: string }
const _home = Optic.id<Env>().at("HOME")
console.log(Result.isSuccess(_home.getResult({ HOME: "/root" })))
// Output: true
console.log(Result.isFailure(_home.getResult({ PATH: "/bin" })))
// Output: true
// replace returns original on failure
console.log(_home.replace("/new", { PATH: "/bin" }))
// Output: { PATH: "/bin" }
Optional<function (type parameter) S in Optional<in out S, in out A>.optionalKey<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `optionalKey` on a union type">): Optional<S, A[Key] | undefined>S, function (type parameter) A in Optional<in out S, in out A>.optionalKey<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `optionalKey` on a union type">): Optional<S, A[Key] | undefined>A[function (type parameter) Key in Optional<in out S, in out A>.optionalKey<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `optionalKey` on a union type">): Optional<S, A[Key] | undefined>Key] | undefined>
/**
* Adds one or more `Schema` validation checks to the optic chain.
* `getResult` fails when any check fails; `set` passes through unchanged.
*
* **Details**
*
* - On a {@link Prism}, returns a Prism.
* - On an {@link Optional}, returns an Optional.
*
* **Example** (Focusing only on positive numbers)
*
* ```ts
* import { Optic, Result, Schema } from "effect"
*
* const _pos = Optic.id<number>().check(Schema.isGreaterThan(0))
*
* console.log(Result.isSuccess(_pos.getResult(5)))
* // Output: true
*
* console.log(Result.isFailure(_pos.getResult(-1)))
* // Output: true
* ```
*
* @see {@link fromChecks} — standalone prism from checks
*/
Optional<in out S, in out A>.check<S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: SchemaAST.Check<A>[]): Prism<S, A> (+1 overload)Adds one or more Schema validation checks to the optic chain.
getResult fails when any check fails; set passes through unchanged.
Details
- On a
Prism
, returns a Prism.
- On an
Optional
, returns an Optional.
Example (Focusing only on positive numbers)
import { Optic, Result, Schema } from "effect"
const _pos = Optic.id<number>().check(Schema.isGreaterThan(0))
console.log(Result.isSuccess(_pos.getResult(5)))
// Output: true
console.log(Result.isFailure(_pos.getResult(-1)))
// Output: true
check<function (type parameter) S in Optional<in out S, in out A>.check<S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: SchemaAST.Check<A>[]): Prism<S, A>S, function (type parameter) A in Optional<in out S, in out A>.check<S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: SchemaAST.Check<A>[]): Prism<S, A>A>(this: Prism<S, A>(parameter) this: {
set: (a: A) => S;
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { (this: Iso<S, A>, that: Iso<A, B>): Iso<S, B>; (this: Lens<S, A>, that: Lens<A, B>): Lens<S, B>; (this: Prism<S, A>, that: Prism<A, B>): Prism<S, B>; (this: Optional<S, A>, that: Optional<A, B>): Optional<S, B> };
modify: (f: (a: A) => A) => (s: S) => S;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<S, Exclude<A, undefined>>; (): Optional<S, Exclude<A, undefined>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
}
this: interface Prism<in out S, in out A>Focuses on a part A of S that may not be present (e.g. a union
variant or a validated subset).
When to use
Use when the focus is conditional — reading can fail (wrong variant, failed
validation).
- Building a new
S from A does not require the original S.
Details
getResult(s) returns Result.Success<A> when the focus matches, or
Result.Failure<string> with an error message.
set(a) always succeeds and returns a new S.
- Extends
Optional
.
- Composing two Prisms produces a Prism; composing a Prism with a
Example (Narrowing a tagged union)
import { Optic, Result } from "effect"
type Shape =
| { readonly _tag: "Circle"; readonly radius: number }
| { readonly _tag: "Rect"; readonly width: number }
const _circle = Optic.id<Shape>().tag("Circle")
console.log(Result.isSuccess(_circle.getResult({ _tag: "Circle", radius: 5 })))
// Output: true
console.log(Result.isFailure(_circle.getResult({ _tag: "Rect", width: 10 })))
// Output: true
Prism<function (type parameter) S in Optional<in out S, in out A>.check<S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: SchemaAST.Check<A>[]): Prism<S, A>S, function (type parameter) A in Optional<in out S, in out A>.check<S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: SchemaAST.Check<A>[]): Prism<S, A>A>, ...checks: readonly [
SchemaAST.Check<A>,
...Array<SchemaAST.Check<A>>
]
(parameter) checks: {
0: SchemaAST.Check<A>;
length: number;
toString: () => string;
toLocaleString: { (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string };
concat: { (...items: Array<ConcatArray<SchemaAST.Check<A>>>): Array<SchemaAST.Check<A>>; (...items: Array<SchemaAST.Check<A> | ConcatArray<SchemaAST.Check<A>>>): Array<SchemaAST.Check<A>> };
join: (separator?: string) => string;
slice: (start?: number, end?: number) => Array<SchemaAST.Check<A>>;
indexOf: (searchElement: SchemaAST.Check<A>, fromIndex?: number) => number;
lastIndexOf: (searchElement: SchemaAST.Check<A>, fromIndex?: number) => number;
every: { (predicate: (value: SchemaAST.Check<A>, index: number, array: ReadonlyArray<SchemaAST.Check<A>>) => value is S, thisArg?: any): this is readonly S[]; (predicate: (value: SchemaAST.Check<A>, index: number, array: ReadonlyArray<SchemaAST.C…;
some: (predicate: (value: SchemaAST.Check<A>, index: number, array: ReadonlyArray<SchemaAST.Check<A>>) => unknown, thisArg?: any) => boolean;
forEach: (callbackfn: (value: SchemaAST.Check<A>, index: number, array: ReadonlyArray<SchemaAST.Check<A>>) => void, thisArg?: any) => void;
map: (callbackfn: (value: SchemaAST.Check<A>, index: number, array: ReadonlyArray<SchemaAST.Check<A>>) => U, thisArg?: any) => Array<U>;
filter: { (predicate: (value: SchemaAST.Check<A>, index: number, array: ReadonlyArray<SchemaAST.Check<A>>) => value is S, thisArg?: any): Array<S>; (predicate: (value: SchemaAST.Check<A>, index: number, array: ReadonlyArray<SchemaAST.Check<A>>) =>…;
reduce: { (callbackfn: (previousValue: SchemaAST.Check<A>, currentValue: SchemaAST.Check<A>, currentIndex: number, array: ReadonlyArray<SchemaAST.Check<A>>) => SchemaAST.Check<A>): SchemaAST.Check<A>; (callbackfn: (previousValue: SchemaAST.Check<A…;
reduceRight: { (callbackfn: (previousValue: SchemaAST.Check<A>, currentValue: SchemaAST.Check<A>, currentIndex: number, array: ReadonlyArray<SchemaAST.Check<A>>) => SchemaAST.Check<A>): SchemaAST.Check<A>; (callbackfn: (previousValue: SchemaAST.Check<A…;
find: { (predicate: (value: SchemaAST.Check<A>, index: number, obj: ReadonlyArray<SchemaAST.Check<A>>) => value is S, thisArg?: any): S | undefined; (predicate: (value: SchemaAST.Check<A>, index: number, obj: ReadonlyArray<SchemaAST.Check<A>>) =…;
findIndex: (predicate: (value: SchemaAST.Check<A>, index: number, obj: ReadonlyArray<SchemaAST.Check<A>>) => unknown, thisArg?: any) => number;
entries: () => ArrayIterator<[number, SchemaAST.Check<A>]>;
keys: () => ArrayIterator<number>;
values: () => ArrayIterator<SchemaAST.Check<A>>;
includes: (searchElement: SchemaAST.Check<A>, fromIndex?: number) => boolean;
flatMap: (callback: (this: This, value: SchemaAST.Check<A>, index: number, array: Array<SchemaAST.Check<A>>) => U | ReadonlyArray<U>, thisArg?: This | undefined) => Array<U>;
flat: (this: A, depth?: D | undefined) => Array<FlatArray<A, D>>;
at: (index: number) => SchemaAST.Check<A> | undefined;
findLast: { (predicate: (value: SchemaAST.Check<A>, index: number, array: ReadonlyArray<SchemaAST.Check<A>>) => value is S, thisArg?: any): S | undefined; (predicate: (value: SchemaAST.Check<A>, index: number, array: ReadonlyArray<SchemaAST.Check<A>…;
findLastIndex: (predicate: (value: SchemaAST.Check<A>, index: number, array: ReadonlyArray<SchemaAST.Check<A>>) => unknown, thisArg?: any) => number;
toReversed: () => Array<SchemaAST.Check<A>>;
toSorted: (compareFn?: ((a: SchemaAST.Check<A>, b: SchemaAST.Check<A>) => number) | undefined) => Array<SchemaAST.Check<A>>;
toSpliced: { (start: number, deleteCount: number, ...items: Array<SchemaAST.Check<A>>): Array<SchemaAST.Check<A>>; (start: number, deleteCount?: number): Array<SchemaAST.Check<A>> };
with: (index: number, value: SchemaAST.Check<A>) => Array<SchemaAST.Check<A>>;
}
checks: readonly [import SchemaASTSchemaAST.type Check<T> =
| SchemaAST.Filter<T>
| SchemaAST.FilterGroup<T>
Check<function (type parameter) A in Optional<in out S, in out A>.check<S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: SchemaAST.Check<A>[]): Prism<S, A>A>, ...interface Array<T>Array<import SchemaASTSchemaAST.type Check<T> =
| SchemaAST.Filter<T>
| SchemaAST.FilterGroup<T>
Check<function (type parameter) A in Optional<in out S, in out A>.check<S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: SchemaAST.Check<A>[]): Prism<S, A>A>>]): interface Prism<in out S, in out A>Focuses on a part A of S that may not be present (e.g. a union
variant or a validated subset).
When to use
Use when the focus is conditional — reading can fail (wrong variant, failed
validation).
- Building a new
S from A does not require the original S.
Details
getResult(s) returns Result.Success<A> when the focus matches, or
Result.Failure<string> with an error message.
set(a) always succeeds and returns a new S.
- Extends
Optional
.
- Composing two Prisms produces a Prism; composing a Prism with a
Example (Narrowing a tagged union)
import { Optic, Result } from "effect"
type Shape =
| { readonly _tag: "Circle"; readonly radius: number }
| { readonly _tag: "Rect"; readonly width: number }
const _circle = Optic.id<Shape>().tag("Circle")
console.log(Result.isSuccess(_circle.getResult({ _tag: "Circle", radius: 5 })))
// Output: true
console.log(Result.isFailure(_circle.getResult({ _tag: "Rect", width: 10 })))
// Output: true
Prism<function (type parameter) S in Optional<in out S, in out A>.check<S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: SchemaAST.Check<A>[]): Prism<S, A>S, function (type parameter) A in Optional<in out S, in out A>.check<S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: SchemaAST.Check<A>[]): Prism<S, A>A>
Optional<in out S, in out A>.check<S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: SchemaAST.Check<A>[]): Optional<S, A> (+1 overload)Adds one or more Schema validation checks to the optic chain.
getResult fails when any check fails; set passes through unchanged.
Details
- On a
Prism
, returns a Prism.
- On an
Optional
, returns an Optional.
Example (Focusing only on positive numbers)
import { Optic, Result, Schema } from "effect"
const _pos = Optic.id<number>().check(Schema.isGreaterThan(0))
console.log(Result.isSuccess(_pos.getResult(5)))
// Output: true
console.log(Result.isFailure(_pos.getResult(-1)))
// Output: true
check<function (type parameter) S in Optional<in out S, in out A>.check<S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: SchemaAST.Check<A>[]): Optional<S, A>S, function (type parameter) A in Optional<in out S, in out A>.check<S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: SchemaAST.Check<A>[]): Optional<S, A>A>(
this: Optional<S, A>(parameter) this: {
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { (this: Iso<S, A>, that: Iso<A, B>): Iso<S, B>; (this: Lens<S, A>, that: Lens<A, B>): Lens<S, B>; (this: Prism<S, A>, that: Prism<A, B>): Prism<S, B>; (this: Optional<S, A>, that: Optional<A, B>): Optional<S, B> };
modify: (f: (a: A) => A) => (s: S) => S;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<S, Exclude<A, undefined>>; (): Optional<S, Exclude<A, undefined>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
}
this: interface Optional<in out S, in out A>The most general optic — both reading and writing can fail.
When to use
Use when the focus may not exist in S and writing a new A back may also
fail, for example when the source no longer matches the expected shape. This
is the base type extended by
Iso
,
Lens
,
Prism
, and
Details
getResult(s) returns Result.Success<A> or Result.Failure<string>.
replaceResult(a, s) returns Result.Success<S> or
Result.Failure<string>.
replace(a, s) returns the original s on failure (never throws).
modify(f) returns the original s on failure (never throws).
- All operations are pure; inputs are never mutated.
Example (Focusing on an optional record key)
import { Optic, Result } from "effect"
type Env = { [key: string]: string }
const _home = Optic.id<Env>().at("HOME")
console.log(Result.isSuccess(_home.getResult({ HOME: "/root" })))
// Output: true
console.log(Result.isFailure(_home.getResult({ PATH: "/bin" })))
// Output: true
// replace returns original on failure
console.log(_home.replace("/new", { PATH: "/bin" }))
// Output: { PATH: "/bin" }
Optional<function (type parameter) S in Optional<in out S, in out A>.check<S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: SchemaAST.Check<A>[]): Optional<S, A>S, function (type parameter) A in Optional<in out S, in out A>.check<S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: SchemaAST.Check<A>[]): Optional<S, A>A>,
...checks: readonly [
SchemaAST.Check<A>,
...Array<SchemaAST.Check<A>>
]
(parameter) checks: {
0: SchemaAST.Check<A>;
length: number;
toString: () => string;
toLocaleString: { (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string };
concat: { (...items: Array<ConcatArray<SchemaAST.Check<A>>>): Array<SchemaAST.Check<A>>; (...items: Array<SchemaAST.Check<A> | ConcatArray<SchemaAST.Check<A>>>): Array<SchemaAST.Check<A>> };
join: (separator?: string) => string;
slice: (start?: number, end?: number) => Array<SchemaAST.Check<A>>;
indexOf: (searchElement: SchemaAST.Check<A>, fromIndex?: number) => number;
lastIndexOf: (searchElement: SchemaAST.Check<A>, fromIndex?: number) => number;
every: { (predicate: (value: SchemaAST.Check<A>, index: number, array: ReadonlyArray<SchemaAST.Check<A>>) => value is S, thisArg?: any): this is readonly S[]; (predicate: (value: SchemaAST.Check<A>, index: number, array: ReadonlyArray<SchemaAST.C…;
some: (predicate: (value: SchemaAST.Check<A>, index: number, array: ReadonlyArray<SchemaAST.Check<A>>) => unknown, thisArg?: any) => boolean;
forEach: (callbackfn: (value: SchemaAST.Check<A>, index: number, array: ReadonlyArray<SchemaAST.Check<A>>) => void, thisArg?: any) => void;
map: (callbackfn: (value: SchemaAST.Check<A>, index: number, array: ReadonlyArray<SchemaAST.Check<A>>) => U, thisArg?: any) => Array<U>;
filter: { (predicate: (value: SchemaAST.Check<A>, index: number, array: ReadonlyArray<SchemaAST.Check<A>>) => value is S, thisArg?: any): Array<S>; (predicate: (value: SchemaAST.Check<A>, index: number, array: ReadonlyArray<SchemaAST.Check<A>>) =>…;
reduce: { (callbackfn: (previousValue: SchemaAST.Check<A>, currentValue: SchemaAST.Check<A>, currentIndex: number, array: ReadonlyArray<SchemaAST.Check<A>>) => SchemaAST.Check<A>): SchemaAST.Check<A>; (callbackfn: (previousValue: SchemaAST.Check<A…;
reduceRight: { (callbackfn: (previousValue: SchemaAST.Check<A>, currentValue: SchemaAST.Check<A>, currentIndex: number, array: ReadonlyArray<SchemaAST.Check<A>>) => SchemaAST.Check<A>): SchemaAST.Check<A>; (callbackfn: (previousValue: SchemaAST.Check<A…;
find: { (predicate: (value: SchemaAST.Check<A>, index: number, obj: ReadonlyArray<SchemaAST.Check<A>>) => value is S, thisArg?: any): S | undefined; (predicate: (value: SchemaAST.Check<A>, index: number, obj: ReadonlyArray<SchemaAST.Check<A>>) =…;
findIndex: (predicate: (value: SchemaAST.Check<A>, index: number, obj: ReadonlyArray<SchemaAST.Check<A>>) => unknown, thisArg?: any) => number;
entries: () => ArrayIterator<[number, SchemaAST.Check<A>]>;
keys: () => ArrayIterator<number>;
values: () => ArrayIterator<SchemaAST.Check<A>>;
includes: (searchElement: SchemaAST.Check<A>, fromIndex?: number) => boolean;
flatMap: (callback: (this: This, value: SchemaAST.Check<A>, index: number, array: Array<SchemaAST.Check<A>>) => U | ReadonlyArray<U>, thisArg?: This | undefined) => Array<U>;
flat: (this: A, depth?: D | undefined) => Array<FlatArray<A, D>>;
at: (index: number) => SchemaAST.Check<A> | undefined;
findLast: { (predicate: (value: SchemaAST.Check<A>, index: number, array: ReadonlyArray<SchemaAST.Check<A>>) => value is S, thisArg?: any): S | undefined; (predicate: (value: SchemaAST.Check<A>, index: number, array: ReadonlyArray<SchemaAST.Check<A>…;
findLastIndex: (predicate: (value: SchemaAST.Check<A>, index: number, array: ReadonlyArray<SchemaAST.Check<A>>) => unknown, thisArg?: any) => number;
toReversed: () => Array<SchemaAST.Check<A>>;
toSorted: (compareFn?: ((a: SchemaAST.Check<A>, b: SchemaAST.Check<A>) => number) | undefined) => Array<SchemaAST.Check<A>>;
toSpliced: { (start: number, deleteCount: number, ...items: Array<SchemaAST.Check<A>>): Array<SchemaAST.Check<A>>; (start: number, deleteCount?: number): Array<SchemaAST.Check<A>> };
with: (index: number, value: SchemaAST.Check<A>) => Array<SchemaAST.Check<A>>;
}
checks: readonly [import SchemaASTSchemaAST.type Check<T> =
| SchemaAST.Filter<T>
| SchemaAST.FilterGroup<T>
Check<function (type parameter) A in Optional<in out S, in out A>.check<S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: SchemaAST.Check<A>[]): Optional<S, A>A>, ...interface Array<T>Array<import SchemaASTSchemaAST.type Check<T> =
| SchemaAST.Filter<T>
| SchemaAST.FilterGroup<T>
Check<function (type parameter) A in Optional<in out S, in out A>.check<S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: SchemaAST.Check<A>[]): Optional<S, A>A>>]
): interface Optional<in out S, in out A>The most general optic — both reading and writing can fail.
When to use
Use when the focus may not exist in S and writing a new A back may also
fail, for example when the source no longer matches the expected shape. This
is the base type extended by
Iso
,
Lens
,
Prism
, and
Details
getResult(s) returns Result.Success<A> or Result.Failure<string>.
replaceResult(a, s) returns Result.Success<S> or
Result.Failure<string>.
replace(a, s) returns the original s on failure (never throws).
modify(f) returns the original s on failure (never throws).
- All operations are pure; inputs are never mutated.
Example (Focusing on an optional record key)
import { Optic, Result } from "effect"
type Env = { [key: string]: string }
const _home = Optic.id<Env>().at("HOME")
console.log(Result.isSuccess(_home.getResult({ HOME: "/root" })))
// Output: true
console.log(Result.isFailure(_home.getResult({ PATH: "/bin" })))
// Output: true
// replace returns original on failure
console.log(_home.replace("/new", { PATH: "/bin" }))
// Output: { PATH: "/bin" }
Optional<function (type parameter) S in Optional<in out S, in out A>.check<S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: SchemaAST.Check<A>[]): Optional<S, A>S, function (type parameter) A in Optional<in out S, in out A>.check<S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: SchemaAST.Check<A>[]): Optional<S, A>A>
/**
* Narrows the focus to a subtype `B` using a type guard.
*
* **Details**
*
* - On a {@link Prism}, returns a Prism.
* - On an {@link Optional}, returns an Optional.
* - Pass optional `annotations` to customize the error message.
*
* **Example** (Narrowing a union)
*
* ```ts
* import { Optic, Result } from "effect"
*
* type B = { readonly _tag: "b"; readonly b: number }
* type S = { readonly _tag: "a"; readonly a: string } | B
*
* const _b = Optic.id<S>().refine(
* (s: S): s is B => s._tag === "b",
* { expected: `"b" tag` }
* )
*
* console.log(Result.isSuccess(_b.getResult({ _tag: "b", b: 1 })))
* // Output: true
* ```
*
* @see `.tag()` — shorthand for narrowing by `_tag`
*/
Optional<in out S, in out A>.refine<S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B> (+1 overload)Narrows the focus to a subtype B using a type guard.
Details
- On a
Prism
, returns a Prism.
- On an
Optional
, returns an Optional.
- Pass optional
annotations to customize the error message.
Example (Narrowing a union)
import { Optic, Result } from "effect"
type B = { readonly _tag: "b"; readonly b: number }
type S = { readonly _tag: "a"; readonly a: string } | B
const _b = Optic.id<S>().refine(
(s: S): s is B => s._tag === "b",
{ expected: `"b" tag` }
)
console.log(Result.isSuccess(_b.getResult({ _tag: "b", b: 1 })))
// Output: true
refine<function (type parameter) S in Optional<in out S, in out A>.refine<S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>S, function (type parameter) A in Optional<in out S, in out A>.refine<S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>A, function (type parameter) B in Optional<in out S, in out A>.refine<S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>B extends function (type parameter) A in Optional<in out S, in out A>.refine<S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>A>(
this: Prism<S, A>(parameter) this: {
set: (a: A) => S;
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { (this: Iso<S, A>, that: Iso<A, B>): Iso<S, B>; (this: Lens<S, A>, that: Lens<A, B>): Lens<S, B>; (this: Prism<S, A>, that: Prism<A, B>): Prism<S, B>; (this: Optional<S, A>, that: Optional<A, B>): Optional<S, B> };
modify: (f: (a: A) => A) => (s: S) => S;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<S, Exclude<A, undefined>>; (): Optional<S, Exclude<A, undefined>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
}
this: interface Prism<in out S, in out A>Focuses on a part A of S that may not be present (e.g. a union
variant or a validated subset).
When to use
Use when the focus is conditional — reading can fail (wrong variant, failed
validation).
- Building a new
S from A does not require the original S.
Details
getResult(s) returns Result.Success<A> when the focus matches, or
Result.Failure<string> with an error message.
set(a) always succeeds and returns a new S.
- Extends
Optional
.
- Composing two Prisms produces a Prism; composing a Prism with a
Example (Narrowing a tagged union)
import { Optic, Result } from "effect"
type Shape =
| { readonly _tag: "Circle"; readonly radius: number }
| { readonly _tag: "Rect"; readonly width: number }
const _circle = Optic.id<Shape>().tag("Circle")
console.log(Result.isSuccess(_circle.getResult({ _tag: "Circle", radius: 5 })))
// Output: true
console.log(Result.isFailure(_circle.getResult({ _tag: "Rect", width: 10 })))
// Output: true
Prism<function (type parameter) S in Optional<in out S, in out A>.refine<S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>S, function (type parameter) A in Optional<in out S, in out A>.refine<S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>A>,
refinement: (a: A) => a is Brefinement: (a: Aa: function (type parameter) A in Optional<in out S, in out A>.refine<S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>A) => a: Aa is function (type parameter) B in Optional<in out S, in out A>.refine<S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>B,
annotations: Schema.Annotations.Filter | undefinedannotations?: import SchemaSchema.Annotations.interface Annotations.FilterAnnotations for filter schema nodes (created via Schema.filter). Extends
Augment
with an optional error message, identifier, and metadata.
Filters are intentionally non-parametric to keep them covariant.
Filter
): interface Prism<in out S, in out A>Focuses on a part A of S that may not be present (e.g. a union
variant or a validated subset).
When to use
Use when the focus is conditional — reading can fail (wrong variant, failed
validation).
- Building a new
S from A does not require the original S.
Details
getResult(s) returns Result.Success<A> when the focus matches, or
Result.Failure<string> with an error message.
set(a) always succeeds and returns a new S.
- Extends
Optional
.
- Composing two Prisms produces a Prism; composing a Prism with a
Example (Narrowing a tagged union)
import { Optic, Result } from "effect"
type Shape =
| { readonly _tag: "Circle"; readonly radius: number }
| { readonly _tag: "Rect"; readonly width: number }
const _circle = Optic.id<Shape>().tag("Circle")
console.log(Result.isSuccess(_circle.getResult({ _tag: "Circle", radius: 5 })))
// Output: true
console.log(Result.isFailure(_circle.getResult({ _tag: "Rect", width: 10 })))
// Output: true
Prism<function (type parameter) S in Optional<in out S, in out A>.refine<S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>S, function (type parameter) B in Optional<in out S, in out A>.refine<S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>B>
Optional<in out S, in out A>.refine<S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Optional<S, B> (+1 overload)Narrows the focus to a subtype B using a type guard.
Details
- On a
Prism
, returns a Prism.
- On an
Optional
, returns an Optional.
- Pass optional
annotations to customize the error message.
Example (Narrowing a union)
import { Optic, Result } from "effect"
type B = { readonly _tag: "b"; readonly b: number }
type S = { readonly _tag: "a"; readonly a: string } | B
const _b = Optic.id<S>().refine(
(s: S): s is B => s._tag === "b",
{ expected: `"b" tag` }
)
console.log(Result.isSuccess(_b.getResult({ _tag: "b", b: 1 })))
// Output: true
refine<function (type parameter) S in Optional<in out S, in out A>.refine<S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Optional<S, B>S, function (type parameter) A in Optional<in out S, in out A>.refine<S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Optional<S, B>A, function (type parameter) B in Optional<in out S, in out A>.refine<S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Optional<S, B>B extends function (type parameter) A in Optional<in out S, in out A>.refine<S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Optional<S, B>A>(
this: Optional<S, A>(parameter) this: {
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { (this: Iso<S, A>, that: Iso<A, B>): Iso<S, B>; (this: Lens<S, A>, that: Lens<A, B>): Lens<S, B>; (this: Prism<S, A>, that: Prism<A, B>): Prism<S, B>; (this: Optional<S, A>, that: Optional<A, B>): Optional<S, B> };
modify: (f: (a: A) => A) => (s: S) => S;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<S, Exclude<A, undefined>>; (): Optional<S, Exclude<A, undefined>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
}
this: interface Optional<in out S, in out A>The most general optic — both reading and writing can fail.
When to use
Use when the focus may not exist in S and writing a new A back may also
fail, for example when the source no longer matches the expected shape. This
is the base type extended by
Iso
,
Lens
,
Prism
, and
Details
getResult(s) returns Result.Success<A> or Result.Failure<string>.
replaceResult(a, s) returns Result.Success<S> or
Result.Failure<string>.
replace(a, s) returns the original s on failure (never throws).
modify(f) returns the original s on failure (never throws).
- All operations are pure; inputs are never mutated.
Example (Focusing on an optional record key)
import { Optic, Result } from "effect"
type Env = { [key: string]: string }
const _home = Optic.id<Env>().at("HOME")
console.log(Result.isSuccess(_home.getResult({ HOME: "/root" })))
// Output: true
console.log(Result.isFailure(_home.getResult({ PATH: "/bin" })))
// Output: true
// replace returns original on failure
console.log(_home.replace("/new", { PATH: "/bin" }))
// Output: { PATH: "/bin" }
Optional<function (type parameter) S in Optional<in out S, in out A>.refine<S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Optional<S, B>S, function (type parameter) A in Optional<in out S, in out A>.refine<S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Optional<S, B>A>,
refinement: (a: A) => a is Brefinement: (a: Aa: function (type parameter) A in Optional<in out S, in out A>.refine<S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Optional<S, B>A) => a: Aa is function (type parameter) B in Optional<in out S, in out A>.refine<S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Optional<S, B>B,
annotations: Schema.Annotations.Filter | undefinedannotations?: import SchemaSchema.Annotations.interface Annotations.FilterAnnotations for filter schema nodes (created via Schema.filter). Extends
Augment
with an optional error message, identifier, and metadata.
Filters are intentionally non-parametric to keep them covariant.
Filter
): interface Optional<in out S, in out A>The most general optic — both reading and writing can fail.
When to use
Use when the focus may not exist in S and writing a new A back may also
fail, for example when the source no longer matches the expected shape. This
is the base type extended by
Iso
,
Lens
,
Prism
, and
Details
getResult(s) returns Result.Success<A> or Result.Failure<string>.
replaceResult(a, s) returns Result.Success<S> or
Result.Failure<string>.
replace(a, s) returns the original s on failure (never throws).
modify(f) returns the original s on failure (never throws).
- All operations are pure; inputs are never mutated.
Example (Focusing on an optional record key)
import { Optic, Result } from "effect"
type Env = { [key: string]: string }
const _home = Optic.id<Env>().at("HOME")
console.log(Result.isSuccess(_home.getResult({ HOME: "/root" })))
// Output: true
console.log(Result.isFailure(_home.getResult({ PATH: "/bin" })))
// Output: true
// replace returns original on failure
console.log(_home.replace("/new", { PATH: "/bin" }))
// Output: { PATH: "/bin" }
Optional<function (type parameter) S in Optional<in out S, in out A>.refine<S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Optional<S, B>S, function (type parameter) B in Optional<in out S, in out A>.refine<S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Optional<S, B>B>
/**
* Narrows the focus to the variant of a tagged union with the given
* `_tag` value.
*
* **Details**
*
* - On a {@link Prism}, returns a Prism.
* - On an {@link Optional}, returns an Optional.
* - Shorthand for `.refine(s => s._tag === tag)`.
*
* **Example** (Focusing a tagged variant)
*
* ```ts
* import { Optic, Result } from "effect"
*
* type Shape =
* | { readonly _tag: "Circle"; readonly radius: number }
* | { readonly _tag: "Rect"; readonly width: number }
*
* const _radius = Optic.id<Shape>().tag("Circle").key("radius")
*
* console.log(Result.isSuccess(_radius.getResult({ _tag: "Circle", radius: 5 })))
* // Output: true
*
* console.log(Result.isFailure(_radius.getResult({ _tag: "Rect", width: 10 })))
* // Output: true
* ```
*
* @see `.refine()` — for arbitrary type guards
*/
Optional<in out S, in out A>.tag<S, A extends {
readonly _tag: SchemaAST.LiteralValue;
}, Tag extends A["_tag"]>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, {
readonly _tag: Tag;
}>> (+1 overload)
Narrows the focus to the variant of a tagged union with the given
_tag value.
Details
- On a
Prism
, returns a Prism.
- On an
Optional
, returns an Optional.
- Shorthand for
.refine(s => s._tag === tag).
Example (Focusing a tagged variant)
import { Optic, Result } from "effect"
type Shape =
| { readonly _tag: "Circle"; readonly radius: number }
| { readonly _tag: "Rect"; readonly width: number }
const _radius = Optic.id<Shape>().tag("Circle").key("radius")
console.log(Result.isSuccess(_radius.getResult({ _tag: "Circle", radius: 5 })))
// Output: true
console.log(Result.isFailure(_radius.getResult({ _tag: "Rect", width: 10 })))
// Output: true
tag<function (type parameter) S in Optional<in out S, in out A>.tag<S, A extends {
readonly _tag: SchemaAST.LiteralValue;
}, Tag extends A["_tag"]>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, {
readonly _tag: Tag;
}>>
S, function (type parameter) A in Optional<in out S, in out A>.tag<S, A extends {
readonly _tag: SchemaAST.LiteralValue;
}, Tag extends A["_tag"]>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, {
readonly _tag: Tag;
}>>
A extends { readonly _tag: SchemaAST.LiteralValue_tag: import SchemaASTSchemaAST.type LiteralValue =
| string
| number
| bigint
| boolean
The set of primitive types that can appear as a
Literal
value.
LiteralValue }, function (type parameter) Tag in Optional<in out S, in out A>.tag<S, A extends {
readonly _tag: SchemaAST.LiteralValue;
}, Tag extends A["_tag"]>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, {
readonly _tag: Tag;
}>>
Tag extends function (type parameter) A in Optional<in out S, in out A>.tag<S, A extends {
readonly _tag: SchemaAST.LiteralValue;
}, Tag extends A["_tag"]>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, {
readonly _tag: Tag;
}>>
A["_tag"]>(
this: Prism<S, A>(parameter) this: {
set: (a: A) => S;
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { (this: Iso<S, A>, that: Iso<A, B>): Iso<S, B>; (this: Lens<S, A>, that: Lens<A, B>): Lens<S, B>; (this: Prism<S, A>, that: Prism<A, B>): Prism<S, B>; (this: Optional<S, A>, that: Optional<A, B>): Optional<S, B> };
modify: (f: (a: A) => A) => (s: S) => S;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<S, Exclude<A, undefined>>; (): Optional<S, Exclude<A, undefined>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
}
this: interface Prism<in out S, in out A>Focuses on a part A of S that may not be present (e.g. a union
variant or a validated subset).
When to use
Use when the focus is conditional — reading can fail (wrong variant, failed
validation).
- Building a new
S from A does not require the original S.
Details
getResult(s) returns Result.Success<A> when the focus matches, or
Result.Failure<string> with an error message.
set(a) always succeeds and returns a new S.
- Extends
Optional
.
- Composing two Prisms produces a Prism; composing a Prism with a
Example (Narrowing a tagged union)
import { Optic, Result } from "effect"
type Shape =
| { readonly _tag: "Circle"; readonly radius: number }
| { readonly _tag: "Rect"; readonly width: number }
const _circle = Optic.id<Shape>().tag("Circle")
console.log(Result.isSuccess(_circle.getResult({ _tag: "Circle", radius: 5 })))
// Output: true
console.log(Result.isFailure(_circle.getResult({ _tag: "Rect", width: 10 })))
// Output: true
Prism<function (type parameter) S in Optional<in out S, in out A>.tag<S, A extends {
readonly _tag: SchemaAST.LiteralValue;
}, Tag extends A["_tag"]>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, {
readonly _tag: Tag;
}>>
S, function (type parameter) A in Optional<in out S, in out A>.tag<S, A extends {
readonly _tag: SchemaAST.LiteralValue;
}, Tag extends A["_tag"]>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, {
readonly _tag: Tag;
}>>
A>,
tag: Tag extends A["_tag"]tag: function (type parameter) Tag in Optional<in out S, in out A>.tag<S, A extends {
readonly _tag: SchemaAST.LiteralValue;
}, Tag extends A["_tag"]>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, {
readonly _tag: Tag;
}>>
Tag
): interface Prism<in out S, in out A>Focuses on a part A of S that may not be present (e.g. a union
variant or a validated subset).
When to use
Use when the focus is conditional — reading can fail (wrong variant, failed
validation).
- Building a new
S from A does not require the original S.
Details
getResult(s) returns Result.Success<A> when the focus matches, or
Result.Failure<string> with an error message.
set(a) always succeeds and returns a new S.
- Extends
Optional
.
- Composing two Prisms produces a Prism; composing a Prism with a
Example (Narrowing a tagged union)
import { Optic, Result } from "effect"
type Shape =
| { readonly _tag: "Circle"; readonly radius: number }
| { readonly _tag: "Rect"; readonly width: number }
const _circle = Optic.id<Shape>().tag("Circle")
console.log(Result.isSuccess(_circle.getResult({ _tag: "Circle", radius: 5 })))
// Output: true
console.log(Result.isFailure(_circle.getResult({ _tag: "Rect", width: 10 })))
// Output: true
Prism<function (type parameter) S in Optional<in out S, in out A>.tag<S, A extends {
readonly _tag: SchemaAST.LiteralValue;
}, Tag extends A["_tag"]>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, {
readonly _tag: Tag;
}>>
S, type Extract<T, U> = T extends U
? T
: never
Extract from T those types that are assignable to U
Extract<function (type parameter) A in Optional<in out S, in out A>.tag<S, A extends {
readonly _tag: SchemaAST.LiteralValue;
}, Tag extends A["_tag"]>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, {
readonly _tag: Tag;
}>>
A, { readonly _tag: Tag extends A["_tag"]_tag: function (type parameter) Tag in Optional<in out S, in out A>.tag<S, A extends {
readonly _tag: SchemaAST.LiteralValue;
}, Tag extends A["_tag"]>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, {
readonly _tag: Tag;
}>>
Tag }>>
Optional<in out S, in out A>.tag<S, A extends {
readonly _tag: SchemaAST.LiteralValue;
}, Tag extends A["_tag"]>(this: Optional<S, A>, tag: Tag): Optional<S, Extract<A, {
readonly _tag: Tag;
}>> (+1 overload)
Narrows the focus to the variant of a tagged union with the given
_tag value.
Details
- On a
Prism
, returns a Prism.
- On an
Optional
, returns an Optional.
- Shorthand for
.refine(s => s._tag === tag).
Example (Focusing a tagged variant)
import { Optic, Result } from "effect"
type Shape =
| { readonly _tag: "Circle"; readonly radius: number }
| { readonly _tag: "Rect"; readonly width: number }
const _radius = Optic.id<Shape>().tag("Circle").key("radius")
console.log(Result.isSuccess(_radius.getResult({ _tag: "Circle", radius: 5 })))
// Output: true
console.log(Result.isFailure(_radius.getResult({ _tag: "Rect", width: 10 })))
// Output: true
tag<function (type parameter) S in Optional<in out S, in out A>.tag<S, A extends {
readonly _tag: SchemaAST.LiteralValue;
}, Tag extends A["_tag"]>(this: Optional<S, A>, tag: Tag): Optional<S, Extract<A, {
readonly _tag: Tag;
}>>
S, function (type parameter) A in Optional<in out S, in out A>.tag<S, A extends {
readonly _tag: SchemaAST.LiteralValue;
}, Tag extends A["_tag"]>(this: Optional<S, A>, tag: Tag): Optional<S, Extract<A, {
readonly _tag: Tag;
}>>
A extends { readonly _tag: SchemaAST.LiteralValue_tag: import SchemaASTSchemaAST.type LiteralValue =
| string
| number
| bigint
| boolean
The set of primitive types that can appear as a
Literal
value.
LiteralValue }, function (type parameter) Tag in Optional<in out S, in out A>.tag<S, A extends {
readonly _tag: SchemaAST.LiteralValue;
}, Tag extends A["_tag"]>(this: Optional<S, A>, tag: Tag): Optional<S, Extract<A, {
readonly _tag: Tag;
}>>
Tag extends function (type parameter) A in Optional<in out S, in out A>.tag<S, A extends {
readonly _tag: SchemaAST.LiteralValue;
}, Tag extends A["_tag"]>(this: Optional<S, A>, tag: Tag): Optional<S, Extract<A, {
readonly _tag: Tag;
}>>
A["_tag"]>(
this: Optional<S, A>(parameter) this: {
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { (this: Iso<S, A>, that: Iso<A, B>): Iso<S, B>; (this: Lens<S, A>, that: Lens<A, B>): Lens<S, B>; (this: Prism<S, A>, that: Prism<A, B>): Prism<S, B>; (this: Optional<S, A>, that: Optional<A, B>): Optional<S, B> };
modify: (f: (a: A) => A) => (s: S) => S;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<S, Exclude<A, undefined>>; (): Optional<S, Exclude<A, undefined>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
}
this: interface Optional<in out S, in out A>The most general optic — both reading and writing can fail.
When to use
Use when the focus may not exist in S and writing a new A back may also
fail, for example when the source no longer matches the expected shape. This
is the base type extended by
Iso
,
Lens
,
Prism
, and
Details
getResult(s) returns Result.Success<A> or Result.Failure<string>.
replaceResult(a, s) returns Result.Success<S> or
Result.Failure<string>.
replace(a, s) returns the original s on failure (never throws).
modify(f) returns the original s on failure (never throws).
- All operations are pure; inputs are never mutated.
Example (Focusing on an optional record key)
import { Optic, Result } from "effect"
type Env = { [key: string]: string }
const _home = Optic.id<Env>().at("HOME")
console.log(Result.isSuccess(_home.getResult({ HOME: "/root" })))
// Output: true
console.log(Result.isFailure(_home.getResult({ PATH: "/bin" })))
// Output: true
// replace returns original on failure
console.log(_home.replace("/new", { PATH: "/bin" }))
// Output: { PATH: "/bin" }
Optional<function (type parameter) S in Optional<in out S, in out A>.tag<S, A extends {
readonly _tag: SchemaAST.LiteralValue;
}, Tag extends A["_tag"]>(this: Optional<S, A>, tag: Tag): Optional<S, Extract<A, {
readonly _tag: Tag;
}>>
S, function (type parameter) A in Optional<in out S, in out A>.tag<S, A extends {
readonly _tag: SchemaAST.LiteralValue;
}, Tag extends A["_tag"]>(this: Optional<S, A>, tag: Tag): Optional<S, Extract<A, {
readonly _tag: Tag;
}>>
A>,
tag: Tag extends A["_tag"]tag: function (type parameter) Tag in Optional<in out S, in out A>.tag<S, A extends {
readonly _tag: SchemaAST.LiteralValue;
}, Tag extends A["_tag"]>(this: Optional<S, A>, tag: Tag): Optional<S, Extract<A, {
readonly _tag: Tag;
}>>
Tag
): interface Optional<in out S, in out A>The most general optic — both reading and writing can fail.
When to use
Use when the focus may not exist in S and writing a new A back may also
fail, for example when the source no longer matches the expected shape. This
is the base type extended by
Iso
,
Lens
,
Prism
, and
Details
getResult(s) returns Result.Success<A> or Result.Failure<string>.
replaceResult(a, s) returns Result.Success<S> or
Result.Failure<string>.
replace(a, s) returns the original s on failure (never throws).
modify(f) returns the original s on failure (never throws).
- All operations are pure; inputs are never mutated.
Example (Focusing on an optional record key)
import { Optic, Result } from "effect"
type Env = { [key: string]: string }
const _home = Optic.id<Env>().at("HOME")
console.log(Result.isSuccess(_home.getResult({ HOME: "/root" })))
// Output: true
console.log(Result.isFailure(_home.getResult({ PATH: "/bin" })))
// Output: true
// replace returns original on failure
console.log(_home.replace("/new", { PATH: "/bin" }))
// Output: { PATH: "/bin" }
Optional<function (type parameter) S in Optional<in out S, in out A>.tag<S, A extends {
readonly _tag: SchemaAST.LiteralValue;
}, Tag extends A["_tag"]>(this: Optional<S, A>, tag: Tag): Optional<S, Extract<A, {
readonly _tag: Tag;
}>>
S, type Extract<T, U> = T extends U
? T
: never
Extract from T those types that are assignable to U
Extract<function (type parameter) A in Optional<in out S, in out A>.tag<S, A extends {
readonly _tag: SchemaAST.LiteralValue;
}, Tag extends A["_tag"]>(this: Optional<S, A>, tag: Tag): Optional<S, Extract<A, {
readonly _tag: Tag;
}>>
A, { readonly _tag: Tag extends A["_tag"]_tag: function (type parameter) Tag in Optional<in out S, in out A>.tag<S, A extends {
readonly _tag: SchemaAST.LiteralValue;
}, Tag extends A["_tag"]>(this: Optional<S, A>, tag: Tag): Optional<S, Extract<A, {
readonly _tag: Tag;
}>>
Tag }>>
/**
* Focuses on a key only if it exists (`Object.hasOwn`). Both
* `getResult` and `replaceResult` fail when the key is absent.
*
* **Details**
*
* Unlike `.key()`, which always succeeds on the read side, `.at()` is
* useful for Records or arrays where the key/index may not be present.
*
* - Always returns an {@link Optional}.
* - Does **not** work on union types (compile error).
*
* **Example** (Accessing records safely)
*
* ```ts
* import { Optic, Result } from "effect"
*
* type Env = { [key: string]: number }
* const _x = Optic.id<Env>().at("x")
*
* console.log(Result.isSuccess(_x.getResult({ x: 1 })))
* // Output: true
*
* console.log(Result.isFailure(_x.getResult({ y: 2 })))
* // Output: true
* ```
*
* @see `.key()` — when the key is always present
*/
Optional<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>): Optional<S, A[Key]>Focuses on a key only if it exists (Object.hasOwn). Both
getResult and replaceResult fail when the key is absent.
Details
Unlike .key(), which always succeeds on the read side, .at() is
useful for Records or arrays where the key/index may not be present.
- Always returns an
Optional
.
- Does not work on union types (compile error).
Example (Accessing records safely)
import { Optic, Result } from "effect"
type Env = { [key: string]: number }
const _x = Optic.id<Env>().at("x")
console.log(Result.isSuccess(_x.getResult({ x: 1 })))
// Output: true
console.log(Result.isFailure(_x.getResult({ y: 2 })))
// Output: true
at<function (type parameter) S in Optional<in out S, in out A>.at<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `at` on a union type">): Optional<S, A[Key]>S, function (type parameter) A in Optional<in out S, in out A>.at<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `at` on a union type">): Optional<S, A[Key]>A extends object, function (type parameter) Key in Optional<in out S, in out A>.at<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `at` on a union type">): Optional<S, A[Key]>Key extends keyof function (type parameter) A in Optional<in out S, in out A>.at<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `at` on a union type">): Optional<S, A[Key]>A>(
this: Optional<S, A>(parameter) this: {
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { (this: Iso<S, A>, that: Iso<A, B>): Iso<S, B>; (this: Lens<S, A>, that: Lens<A, B>): Lens<S, B>; (this: Prism<S, A>, that: Prism<A, B>): Prism<S, B>; (this: Optional<S, A>, that: Optional<A, B>): Optional<S, B> };
modify: (f: (a: A) => A) => (s: S) => S;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<S, Exclude<A, undefined>>; (): Optional<S, Exclude<A, undefined>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
}
this: interface Optional<in out S, in out A>The most general optic — both reading and writing can fail.
When to use
Use when the focus may not exist in S and writing a new A back may also
fail, for example when the source no longer matches the expected shape. This
is the base type extended by
Iso
,
Lens
,
Prism
, and
Details
getResult(s) returns Result.Success<A> or Result.Failure<string>.
replaceResult(a, s) returns Result.Success<S> or
Result.Failure<string>.
replace(a, s) returns the original s on failure (never throws).
modify(f) returns the original s on failure (never throws).
- All operations are pure; inputs are never mutated.
Example (Focusing on an optional record key)
import { Optic, Result } from "effect"
type Env = { [key: string]: string }
const _home = Optic.id<Env>().at("HOME")
console.log(Result.isSuccess(_home.getResult({ HOME: "/root" })))
// Output: true
console.log(Result.isFailure(_home.getResult({ PATH: "/bin" })))
// Output: true
// replace returns original on failure
console.log(_home.replace("/new", { PATH: "/bin" }))
// Output: { PATH: "/bin" }
Optional<function (type parameter) S in Optional<in out S, in out A>.at<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `at` on a union type">): Optional<S, A[Key]>S, function (type parameter) A in Optional<in out S, in out A>.at<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `at` on a union type">): Optional<S, A[Key]>A>,
key: Key extends keyof Akey: function (type parameter) Key in Optional<in out S, in out A>.at<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `at` on a union type">): Optional<S, A[Key]>Key,
..._err: ForbidUnion<
A,
"cannot use `at` on a union type"
>
_err: type ForbidUnion<
A,
Message extends string
> = IsUnion<A> extends true ? [Message] : []
ForbidUnion<function (type parameter) A in Optional<in out S, in out A>.at<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `at` on a union type">): Optional<S, A[Key]>A, "cannot use `at` on a union type">
): interface Optional<in out S, in out A>The most general optic — both reading and writing can fail.
When to use
Use when the focus may not exist in S and writing a new A back may also
fail, for example when the source no longer matches the expected shape. This
is the base type extended by
Iso
,
Lens
,
Prism
, and
Details
getResult(s) returns Result.Success<A> or Result.Failure<string>.
replaceResult(a, s) returns Result.Success<S> or
Result.Failure<string>.
replace(a, s) returns the original s on failure (never throws).
modify(f) returns the original s on failure (never throws).
- All operations are pure; inputs are never mutated.
Example (Focusing on an optional record key)
import { Optic, Result } from "effect"
type Env = { [key: string]: string }
const _home = Optic.id<Env>().at("HOME")
console.log(Result.isSuccess(_home.getResult({ HOME: "/root" })))
// Output: true
console.log(Result.isFailure(_home.getResult({ PATH: "/bin" })))
// Output: true
// replace returns original on failure
console.log(_home.replace("/new", { PATH: "/bin" }))
// Output: { PATH: "/bin" }
Optional<function (type parameter) S in Optional<in out S, in out A>.at<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `at` on a union type">): Optional<S, A[Key]>S, function (type parameter) A in Optional<in out S, in out A>.at<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `at` on a union type">): Optional<S, A[Key]>A[function (type parameter) Key in Optional<in out S, in out A>.at<S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, "cannot use `at` on a union type">): Optional<S, A[Key]>Key]>
/**
* Focuses on a subset of keys of the current struct focus.
*
* **Details**
*
* - On a {@link Lens}, returns a Lens.
* - On an {@link Optional}, returns an Optional.
* - Does **not** work on union types (compile error).
*
* **Example** (Picking keys)
*
* ```ts
* import { Optic } from "effect"
*
* type S = { readonly a: string; readonly b: number; readonly c: boolean }
*
* const _ac = Optic.id<S>().pick(["a", "c"])
*
* console.log(_ac.get({ a: "hi", b: 1, c: true }))
* // Output: { a: "hi", c: true }
* ```
*
* @see `.omit()` — the inverse operation
*/
Optional<in out S, in out A>.pick<S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `pick` on a union type">): Lens<S, Pick<A, Keys[number]>> (+1 overload)Focuses on a subset of keys of the current struct focus.
Details
- On a
Lens
, returns a Lens.
- On an
Optional
, returns an Optional.
- Does not work on union types (compile error).
Example (Picking keys)
import { Optic } from "effect"
type S = { readonly a: string; readonly b: number; readonly c: boolean }
const _ac = Optic.id<S>().pick(["a", "c"])
console.log(_ac.get({ a: "hi", b: 1, c: true }))
// Output: { a: "hi", c: true }
pick<function (type parameter) S in Optional<in out S, in out A>.pick<S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `pick` on a union type">): Lens<S, Pick<A, Keys[number]>>S, function (type parameter) A in Optional<in out S, in out A>.pick<S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `pick` on a union type">): Lens<S, Pick<A, Keys[number]>>A, function (type parameter) Keys in Optional<in out S, in out A>.pick<S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `pick` on a union type">): Lens<S, Pick<A, Keys[number]>>Keys extends interface ReadonlyArray<T>ReadonlyArray<keyof function (type parameter) A in Optional<in out S, in out A>.pick<S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `pick` on a union type">): Lens<S, Pick<A, Keys[number]>>A>>(
this: Lens<S, A>(parameter) this: {
get: (s: S) => A;
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { (this: Iso<S, A>, that: Iso<A, B>): Iso<S, B>; (this: Lens<S, A>, that: Lens<A, B>): Lens<S, B>; (this: Prism<S, A>, that: Prism<A, B>): Prism<S, B>; (this: Optional<S, A>, that: Optional<A, B>): Optional<S, B> };
modify: (f: (a: A) => A) => (s: S) => S;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<S, Exclude<A, undefined>>; (): Optional<S, Exclude<A, undefined>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
}
this: interface Lens<in out S, in out A>Focuses on exactly one part A inside a whole S.
When to use
Use when you always have a value to read and need the original S to produce
the updated whole, unlike Iso.
Details
get(s) always succeeds and returns A.
replace(a, s) returns a new S with the focused part replaced.
- Extends
Optional
.
- Composing a Lens with a
Prism
or
Optional
produces an
Optional
.
Example (Focusing on a struct field)
import { Optic } from "effect"
type Person = { readonly name: string; readonly age: number }
const _name = Optic.id<Person>().key("name")
console.log(_name.get({ name: "Alice", age: 30 }))
// Output: "Alice"
Lens<function (type parameter) S in Optional<in out S, in out A>.pick<S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `pick` on a union type">): Lens<S, Pick<A, Keys[number]>>S, function (type parameter) A in Optional<in out S, in out A>.pick<S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `pick` on a union type">): Lens<S, Pick<A, Keys[number]>>A>,
keys: Keys extends ReadonlyArray<keyof A>keys: function (type parameter) Keys in Optional<in out S, in out A>.pick<S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `pick` on a union type">): Lens<S, Pick<A, Keys[number]>>Keys,
..._err: ForbidUnion<
A,
"cannot use `pick` on a union type"
>
_err: type ForbidUnion<
A,
Message extends string
> = IsUnion<A> extends true ? [Message] : []
ForbidUnion<function (type parameter) A in Optional<in out S, in out A>.pick<S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `pick` on a union type">): Lens<S, Pick<A, Keys[number]>>A, "cannot use `pick` on a union type">
): interface Lens<in out S, in out A>Focuses on exactly one part A inside a whole S.
When to use
Use when you always have a value to read and need the original S to produce
the updated whole, unlike Iso.
Details
get(s) always succeeds and returns A.
replace(a, s) returns a new S with the focused part replaced.
- Extends
Optional
.
- Composing a Lens with a
Prism
or
Optional
produces an
Optional
.
Example (Focusing on a struct field)
import { Optic } from "effect"
type Person = { readonly name: string; readonly age: number }
const _name = Optic.id<Person>().key("name")
console.log(_name.get({ name: "Alice", age: 30 }))
// Output: "Alice"
Lens<function (type parameter) S in Optional<in out S, in out A>.pick<S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `pick` on a union type">): Lens<S, Pick<A, Keys[number]>>S, type Pick<T, K extends keyof T> = {
[P in K]: T[P]
}
From T, pick a set of properties whose keys are in the union K
Pick<function (type parameter) A in Optional<in out S, in out A>.pick<S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `pick` on a union type">): Lens<S, Pick<A, Keys[number]>>A, function (type parameter) Keys in Optional<in out S, in out A>.pick<S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `pick` on a union type">): Lens<S, Pick<A, Keys[number]>>Keys[number]>>
Optional<in out S, in out A>.pick<S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `pick` on a union type">): Optional<S, Pick<A, Keys[number]>> (+1 overload)Focuses on a subset of keys of the current struct focus.
Details
- On a
Lens
, returns a Lens.
- On an
Optional
, returns an Optional.
- Does not work on union types (compile error).
Example (Picking keys)
import { Optic } from "effect"
type S = { readonly a: string; readonly b: number; readonly c: boolean }
const _ac = Optic.id<S>().pick(["a", "c"])
console.log(_ac.get({ a: "hi", b: 1, c: true }))
// Output: { a: "hi", c: true }
pick<function (type parameter) S in Optional<in out S, in out A>.pick<S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `pick` on a union type">): Optional<S, Pick<A, Keys[number]>>S, function (type parameter) A in Optional<in out S, in out A>.pick<S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `pick` on a union type">): Optional<S, Pick<A, Keys[number]>>A, function (type parameter) Keys in Optional<in out S, in out A>.pick<S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `pick` on a union type">): Optional<S, Pick<A, Keys[number]>>Keys extends interface ReadonlyArray<T>ReadonlyArray<keyof function (type parameter) A in Optional<in out S, in out A>.pick<S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `pick` on a union type">): Optional<S, Pick<A, Keys[number]>>A>>(
this: Optional<S, A>(parameter) this: {
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { (this: Iso<S, A>, that: Iso<A, B>): Iso<S, B>; (this: Lens<S, A>, that: Lens<A, B>): Lens<S, B>; (this: Prism<S, A>, that: Prism<A, B>): Prism<S, B>; (this: Optional<S, A>, that: Optional<A, B>): Optional<S, B> };
modify: (f: (a: A) => A) => (s: S) => S;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<S, Exclude<A, undefined>>; (): Optional<S, Exclude<A, undefined>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
}
this: interface Optional<in out S, in out A>The most general optic — both reading and writing can fail.
When to use
Use when the focus may not exist in S and writing a new A back may also
fail, for example when the source no longer matches the expected shape. This
is the base type extended by
Iso
,
Lens
,
Prism
, and
Details
getResult(s) returns Result.Success<A> or Result.Failure<string>.
replaceResult(a, s) returns Result.Success<S> or
Result.Failure<string>.
replace(a, s) returns the original s on failure (never throws).
modify(f) returns the original s on failure (never throws).
- All operations are pure; inputs are never mutated.
Example (Focusing on an optional record key)
import { Optic, Result } from "effect"
type Env = { [key: string]: string }
const _home = Optic.id<Env>().at("HOME")
console.log(Result.isSuccess(_home.getResult({ HOME: "/root" })))
// Output: true
console.log(Result.isFailure(_home.getResult({ PATH: "/bin" })))
// Output: true
// replace returns original on failure
console.log(_home.replace("/new", { PATH: "/bin" }))
// Output: { PATH: "/bin" }
Optional<function (type parameter) S in Optional<in out S, in out A>.pick<S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `pick` on a union type">): Optional<S, Pick<A, Keys[number]>>S, function (type parameter) A in Optional<in out S, in out A>.pick<S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `pick` on a union type">): Optional<S, Pick<A, Keys[number]>>A>,
keys: Keys extends ReadonlyArray<keyof A>keys: function (type parameter) Keys in Optional<in out S, in out A>.pick<S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `pick` on a union type">): Optional<S, Pick<A, Keys[number]>>Keys,
..._err: ForbidUnion<
A,
"cannot use `pick` on a union type"
>
_err: type ForbidUnion<
A,
Message extends string
> = IsUnion<A> extends true ? [Message] : []
ForbidUnion<function (type parameter) A in Optional<in out S, in out A>.pick<S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `pick` on a union type">): Optional<S, Pick<A, Keys[number]>>A, "cannot use `pick` on a union type">
): interface Optional<in out S, in out A>The most general optic — both reading and writing can fail.
When to use
Use when the focus may not exist in S and writing a new A back may also
fail, for example when the source no longer matches the expected shape. This
is the base type extended by
Iso
,
Lens
,
Prism
, and
Details
getResult(s) returns Result.Success<A> or Result.Failure<string>.
replaceResult(a, s) returns Result.Success<S> or
Result.Failure<string>.
replace(a, s) returns the original s on failure (never throws).
modify(f) returns the original s on failure (never throws).
- All operations are pure; inputs are never mutated.
Example (Focusing on an optional record key)
import { Optic, Result } from "effect"
type Env = { [key: string]: string }
const _home = Optic.id<Env>().at("HOME")
console.log(Result.isSuccess(_home.getResult({ HOME: "/root" })))
// Output: true
console.log(Result.isFailure(_home.getResult({ PATH: "/bin" })))
// Output: true
// replace returns original on failure
console.log(_home.replace("/new", { PATH: "/bin" }))
// Output: { PATH: "/bin" }
Optional<function (type parameter) S in Optional<in out S, in out A>.pick<S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `pick` on a union type">): Optional<S, Pick<A, Keys[number]>>S, type Pick<T, K extends keyof T> = {
[P in K]: T[P]
}
From T, pick a set of properties whose keys are in the union K
Pick<function (type parameter) A in Optional<in out S, in out A>.pick<S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `pick` on a union type">): Optional<S, Pick<A, Keys[number]>>A, function (type parameter) Keys in Optional<in out S, in out A>.pick<S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `pick` on a union type">): Optional<S, Pick<A, Keys[number]>>Keys[number]>>
/**
* Focuses on all keys **except** the specified ones.
*
* **Details**
*
* - On a {@link Lens}, returns a Lens.
* - On an {@link Optional}, returns an Optional.
* - Does **not** work on union types (compile error).
*
* **Example** (Omitting keys)
*
* ```ts
* import { Optic } from "effect"
*
* type S = { readonly a: string; readonly b: number; readonly c: boolean }
*
* const _ac = Optic.id<S>().omit(["b"])
*
* console.log(_ac.get({ a: "hi", b: 1, c: true }))
* // Output: { a: "hi", c: true }
* ```
*
* @see `.pick()` — the inverse operation
*
* @since 4.0.0
*/
Optional<in out S, in out A>.omit<S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `omit` on a union type">): Lens<S, Omit<A, Keys[number]>> (+1 overload)Focuses on all keys except the specified ones.
Details
- On a
Lens
, returns a Lens.
- On an
Optional
, returns an Optional.
- Does not work on union types (compile error).
Example (Omitting keys)
import { Optic } from "effect"
type S = { readonly a: string; readonly b: number; readonly c: boolean }
const _ac = Optic.id<S>().omit(["b"])
console.log(_ac.get({ a: "hi", b: 1, c: true }))
// Output: { a: "hi", c: true }
omit<function (type parameter) S in Optional<in out S, in out A>.omit<S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `omit` on a union type">): Lens<S, Omit<A, Keys[number]>>S, function (type parameter) A in Optional<in out S, in out A>.omit<S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `omit` on a union type">): Lens<S, Omit<A, Keys[number]>>A, function (type parameter) Keys in Optional<in out S, in out A>.omit<S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `omit` on a union type">): Lens<S, Omit<A, Keys[number]>>Keys extends interface ReadonlyArray<T>ReadonlyArray<keyof function (type parameter) A in Optional<in out S, in out A>.omit<S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `omit` on a union type">): Lens<S, Omit<A, Keys[number]>>A>>(
this: Lens<S, A>(parameter) this: {
get: (s: S) => A;
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { (this: Iso<S, A>, that: Iso<A, B>): Iso<S, B>; (this: Lens<S, A>, that: Lens<A, B>): Lens<S, B>; (this: Prism<S, A>, that: Prism<A, B>): Prism<S, B>; (this: Optional<S, A>, that: Optional<A, B>): Optional<S, B> };
modify: (f: (a: A) => A) => (s: S) => S;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<S, Exclude<A, undefined>>; (): Optional<S, Exclude<A, undefined>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
}
this: interface Lens<in out S, in out A>Focuses on exactly one part A inside a whole S.
When to use
Use when you always have a value to read and need the original S to produce
the updated whole, unlike Iso.
Details
get(s) always succeeds and returns A.
replace(a, s) returns a new S with the focused part replaced.
- Extends
Optional
.
- Composing a Lens with a
Prism
or
Optional
produces an
Optional
.
Example (Focusing on a struct field)
import { Optic } from "effect"
type Person = { readonly name: string; readonly age: number }
const _name = Optic.id<Person>().key("name")
console.log(_name.get({ name: "Alice", age: 30 }))
// Output: "Alice"
Lens<function (type parameter) S in Optional<in out S, in out A>.omit<S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `omit` on a union type">): Lens<S, Omit<A, Keys[number]>>S, function (type parameter) A in Optional<in out S, in out A>.omit<S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `omit` on a union type">): Lens<S, Omit<A, Keys[number]>>A>,
keys: Keys extends ReadonlyArray<keyof A>keys: function (type parameter) Keys in Optional<in out S, in out A>.omit<S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `omit` on a union type">): Lens<S, Omit<A, Keys[number]>>Keys,
..._err: ForbidUnion<
A,
"cannot use `omit` on a union type"
>
_err: type ForbidUnion<
A,
Message extends string
> = IsUnion<A> extends true ? [Message] : []
ForbidUnion<function (type parameter) A in Optional<in out S, in out A>.omit<S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `omit` on a union type">): Lens<S, Omit<A, Keys[number]>>A, "cannot use `omit` on a union type">
): interface Lens<in out S, in out A>Focuses on exactly one part A inside a whole S.
When to use
Use when you always have a value to read and need the original S to produce
the updated whole, unlike Iso.
Details
get(s) always succeeds and returns A.
replace(a, s) returns a new S with the focused part replaced.
- Extends
Optional
.
- Composing a Lens with a
Prism
or
Optional
produces an
Optional
.
Example (Focusing on a struct field)
import { Optic } from "effect"
type Person = { readonly name: string; readonly age: number }
const _name = Optic.id<Person>().key("name")
console.log(_name.get({ name: "Alice", age: 30 }))
// Output: "Alice"
Lens<function (type parameter) S in Optional<in out S, in out A>.omit<S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `omit` on a union type">): Lens<S, Omit<A, Keys[number]>>S, 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<function (type parameter) A in Optional<in out S, in out A>.omit<S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `omit` on a union type">): Lens<S, Omit<A, Keys[number]>>A, function (type parameter) Keys in Optional<in out S, in out A>.omit<S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `omit` on a union type">): Lens<S, Omit<A, Keys[number]>>Keys[number]>>
Optional<in out S, in out A>.omit<S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `omit` on a union type">): Optional<S, Omit<A, Keys[number]>> (+1 overload)Focuses on all keys except the specified ones.
Details
- On a
Lens
, returns a Lens.
- On an
Optional
, returns an Optional.
- Does not work on union types (compile error).
Example (Omitting keys)
import { Optic } from "effect"
type S = { readonly a: string; readonly b: number; readonly c: boolean }
const _ac = Optic.id<S>().omit(["b"])
console.log(_ac.get({ a: "hi", b: 1, c: true }))
// Output: { a: "hi", c: true }
omit<function (type parameter) S in Optional<in out S, in out A>.omit<S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `omit` on a union type">): Optional<S, Omit<A, Keys[number]>>S, function (type parameter) A in Optional<in out S, in out A>.omit<S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `omit` on a union type">): Optional<S, Omit<A, Keys[number]>>A, function (type parameter) Keys in Optional<in out S, in out A>.omit<S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `omit` on a union type">): Optional<S, Omit<A, Keys[number]>>Keys extends interface ReadonlyArray<T>ReadonlyArray<keyof function (type parameter) A in Optional<in out S, in out A>.omit<S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `omit` on a union type">): Optional<S, Omit<A, Keys[number]>>A>>(
this: Optional<S, A>(parameter) this: {
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { (this: Iso<S, A>, that: Iso<A, B>): Iso<S, B>; (this: Lens<S, A>, that: Lens<A, B>): Lens<S, B>; (this: Prism<S, A>, that: Prism<A, B>): Prism<S, B>; (this: Optional<S, A>, that: Optional<A, B>): Optional<S, B> };
modify: (f: (a: A) => A) => (s: S) => S;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<S, Exclude<A, undefined>>; (): Optional<S, Exclude<A, undefined>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
}
this: interface Optional<in out S, in out A>The most general optic — both reading and writing can fail.
When to use
Use when the focus may not exist in S and writing a new A back may also
fail, for example when the source no longer matches the expected shape. This
is the base type extended by
Iso
,
Lens
,
Prism
, and
Details
getResult(s) returns Result.Success<A> or Result.Failure<string>.
replaceResult(a, s) returns Result.Success<S> or
Result.Failure<string>.
replace(a, s) returns the original s on failure (never throws).
modify(f) returns the original s on failure (never throws).
- All operations are pure; inputs are never mutated.
Example (Focusing on an optional record key)
import { Optic, Result } from "effect"
type Env = { [key: string]: string }
const _home = Optic.id<Env>().at("HOME")
console.log(Result.isSuccess(_home.getResult({ HOME: "/root" })))
// Output: true
console.log(Result.isFailure(_home.getResult({ PATH: "/bin" })))
// Output: true
// replace returns original on failure
console.log(_home.replace("/new", { PATH: "/bin" }))
// Output: { PATH: "/bin" }
Optional<function (type parameter) S in Optional<in out S, in out A>.omit<S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `omit` on a union type">): Optional<S, Omit<A, Keys[number]>>S, function (type parameter) A in Optional<in out S, in out A>.omit<S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `omit` on a union type">): Optional<S, Omit<A, Keys[number]>>A>,
keys: Keys extends ReadonlyArray<keyof A>keys: function (type parameter) Keys in Optional<in out S, in out A>.omit<S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `omit` on a union type">): Optional<S, Omit<A, Keys[number]>>Keys,
..._err: ForbidUnion<
A,
"cannot use `omit` on a union type"
>
_err: type ForbidUnion<
A,
Message extends string
> = IsUnion<A> extends true ? [Message] : []
ForbidUnion<function (type parameter) A in Optional<in out S, in out A>.omit<S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `omit` on a union type">): Optional<S, Omit<A, Keys[number]>>A, "cannot use `omit` on a union type">
): interface Optional<in out S, in out A>The most general optic — both reading and writing can fail.
When to use
Use when the focus may not exist in S and writing a new A back may also
fail, for example when the source no longer matches the expected shape. This
is the base type extended by
Iso
,
Lens
,
Prism
, and
Details
getResult(s) returns Result.Success<A> or Result.Failure<string>.
replaceResult(a, s) returns Result.Success<S> or
Result.Failure<string>.
replace(a, s) returns the original s on failure (never throws).
modify(f) returns the original s on failure (never throws).
- All operations are pure; inputs are never mutated.
Example (Focusing on an optional record key)
import { Optic, Result } from "effect"
type Env = { [key: string]: string }
const _home = Optic.id<Env>().at("HOME")
console.log(Result.isSuccess(_home.getResult({ HOME: "/root" })))
// Output: true
console.log(Result.isFailure(_home.getResult({ PATH: "/bin" })))
// Output: true
// replace returns original on failure
console.log(_home.replace("/new", { PATH: "/bin" }))
// Output: { PATH: "/bin" }
Optional<function (type parameter) S in Optional<in out S, in out A>.omit<S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `omit` on a union type">): Optional<S, Omit<A, Keys[number]>>S, 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<function (type parameter) A in Optional<in out S, in out A>.omit<S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `omit` on a union type">): Optional<S, Omit<A, Keys[number]>>A, function (type parameter) Keys in Optional<in out S, in out A>.omit<S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, keys: Keys, ..._err: ForbidUnion<A, "cannot use `omit` on a union type">): Optional<S, Omit<A, Keys[number]>>Keys[number]>>
/**
* Filters out `undefined` from the focus, producing a {@link Prism}.
* `getResult` fails when the focus is `undefined`.
*
* **Example** (Filtering undefined values)
*
* ```ts
* import { Optic, Result } from "effect"
*
* const _defined = Optic.id<number | undefined>().notUndefined()
*
* console.log(Result.isSuccess(_defined.getResult(42)))
* // Output: true
*
* console.log(Result.isFailure(_defined.getResult(undefined)))
* // Output: true
* ```
*
* @since 4.0.0
*/
Optional<in out S, in out A>.notUndefined(): Prism<S, Exclude<A, undefined>> (+1 overload)Filters out undefined from the focus, producing a
Prism
.
getResult fails when the focus is undefined.
Example (Filtering undefined values)
import { Optic, Result } from "effect"
const _defined = Optic.id<number | undefined>().notUndefined()
console.log(Result.isSuccess(_defined.getResult(42)))
// Output: true
console.log(Result.isFailure(_defined.getResult(undefined)))
// Output: true
notUndefined(): interface Prism<in out S, in out A>Focuses on a part A of S that may not be present (e.g. a union
variant or a validated subset).
When to use
Use when the focus is conditional — reading can fail (wrong variant, failed
validation).
- Building a new
S from A does not require the original S.
Details
getResult(s) returns Result.Success<A> when the focus matches, or
Result.Failure<string> with an error message.
set(a) always succeeds and returns a new S.
- Extends
Optional
.
- Composing two Prisms produces a Prism; composing a Prism with a
Example (Narrowing a tagged union)
import { Optic, Result } from "effect"
type Shape =
| { readonly _tag: "Circle"; readonly radius: number }
| { readonly _tag: "Rect"; readonly width: number }
const _circle = Optic.id<Shape>().tag("Circle")
console.log(Result.isSuccess(_circle.getResult({ _tag: "Circle", radius: 5 })))
// Output: true
console.log(Result.isFailure(_circle.getResult({ _tag: "Rect", width: 10 })))
// Output: true
Prism<function (type parameter) S in Optional<in out S, in out A>S, type Exclude<T, U> = T extends U
? never
: T
Exclude from T those types that are assignable to U
Exclude<function (type parameter) A in Optional<in out S, in out A>A, undefined>>
Optional<in out S, in out A>.notUndefined(): Optional<S, Exclude<A, undefined>> (+1 overload)Filters out undefined from the focus, producing a
Prism
.
getResult fails when the focus is undefined.
Example (Filtering undefined values)
import { Optic, Result } from "effect"
const _defined = Optic.id<number | undefined>().notUndefined()
console.log(Result.isSuccess(_defined.getResult(42)))
// Output: true
console.log(Result.isFailure(_defined.getResult(undefined)))
// Output: true
notUndefined(): interface Optional<in out S, in out A>The most general optic — both reading and writing can fail.
When to use
Use when the focus may not exist in S and writing a new A back may also
fail, for example when the source no longer matches the expected shape. This
is the base type extended by
Iso
,
Lens
,
Prism
, and
Details
getResult(s) returns Result.Success<A> or Result.Failure<string>.
replaceResult(a, s) returns Result.Success<S> or
Result.Failure<string>.
replace(a, s) returns the original s on failure (never throws).
modify(f) returns the original s on failure (never throws).
- All operations are pure; inputs are never mutated.
Example (Focusing on an optional record key)
import { Optic, Result } from "effect"
type Env = { [key: string]: string }
const _home = Optic.id<Env>().at("HOME")
console.log(Result.isSuccess(_home.getResult({ HOME: "/root" })))
// Output: true
console.log(Result.isFailure(_home.getResult({ PATH: "/bin" })))
// Output: true
// replace returns original on failure
console.log(_home.replace("/new", { PATH: "/bin" }))
// Output: { PATH: "/bin" }
Optional<function (type parameter) S in Optional<in out S, in out A>S, type Exclude<T, U> = T extends U
? never
: T
Exclude from T those types that are assignable to U
Exclude<function (type parameter) A in Optional<in out S, in out A>A, undefined>>
/**
* Focuses **all elements** of an array-like focus and optionally narrows
* to a subset using an element-level optic.
* Available only on {@link Traversal} (i.e. when `A` is
* `ReadonlyArray<Element>`). Returns a new Traversal focused on the
* selected elements.
*
* **Details**
*
* - **getResult** collects the values focused by `f(id<A>())` for each
* element. Non-focusable elements are skipped.
* - **replaceResult** expects exactly as many values as were collected by
* `getResult` and writes them back in order. Fails with a
* length-mismatch error if counts differ.
*
* **Example** (Incrementing liked posts)
*
* ```ts
* import { Optic, Schema } from "effect"
*
* type Post = { title: string; likes: number }
* type S = { user: { posts: ReadonlyArray<Post> } }
*
* const _likes = Optic.id<S>()
* .key("user")
* .key("posts")
* .forEach((post) => post.key("likes").check(Schema.isGreaterThan(0)))
*
* const addLike = _likes.modifyAll((n) => n + 1)
*
* console.log(
* addLike({
* user: { posts: [{ title: "a", likes: 0 }, { title: "b", likes: 1 }] }
* })
* )
* // Output: { user: { posts: [{ title: "a", likes: 0 }, { title: "b", likes: 2 }] } }
* ```
*
* @see {@link getAll} — extract all focused elements as an array
* @see `.modifyAll()` — apply a function to every focused element
*/
Optional<S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>): Traversal<S, B>Focuses all elements of an array-like focus and optionally narrows
to a subset using an element-level optic.
Available only on
Traversal
(i.e. when A is
ReadonlyArray<Element>). Returns a new Traversal focused on the
selected elements.
Details
- getResult collects the values focused by
f(id<A>()) for each
element. Non-focusable elements are skipped.
- replaceResult expects exactly as many values as were collected by
getResult and writes them back in order. Fails with a
length-mismatch error if counts differ.
Example (Incrementing liked posts)
import { Optic, Schema } from "effect"
type Post = { title: string; likes: number }
type S = { user: { posts: ReadonlyArray<Post> } }
const _likes = Optic.id<S>()
.key("user")
.key("posts")
.forEach((post) => post.key("likes").check(Schema.isGreaterThan(0)))
const addLike = _likes.modifyAll((n) => n + 1)
console.log(
addLike({
user: { posts: [{ title: "a", likes: 0 }, { title: "b", likes: 1 }] }
})
)
// Output: { user: { posts: [{ title: "a", likes: 0 }, { title: "b", likes: 2 }] } }
forEach<function (type parameter) S in Optional<in out S, in out A>.forEach<S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>): Traversal<S, B>S, function (type parameter) A in Optional<in out S, in out A>.forEach<S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>): Traversal<S, B>A, function (type parameter) B in Optional<in out S, in out A>.forEach<S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>): Traversal<S, B>B>(this: Traversal<S, A>(parameter) this: {
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { (this: Iso<S, ReadonlyArray<A>>, that: Iso<ReadonlyArray<A>, B>): Iso<S, B>; (this: Lens<S, ReadonlyArray<A>>, that: Lens<ReadonlyArray<A>, B>): Lens<S, B>; (this: Prism<S, ReadonlyArray<A>>, that: Prism<ReadonlyArray<A>, B>): Prism<S, B…;
modify: (f: (a: ReadonlyArray<A>) => ReadonlyArray<A>) => (s: S) => S;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<S, ReadonlyArray<A>>; (): Optional<S, ReadonlyArray<A>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
}
this: interface Traversal<in out S, in out A>An optic that focuses on zero or more elements of type A inside S.
When to use
Use when you want to read/update multiple elements at once (e.g. all items in
an array, or a filtered subset).
Details
- Technically
Optional<S, ReadonlyArray<A>> — the focused value is an
array of all matched elements.
- Use
.forEach() to add per-element sub-optics (filtering, drilling
deeper).
- Use
.modifyAll(f) to map a function over every focused element.
- Use
getAll
to extract all focused elements as a plain array.
Example (Traversing array elements with a filter)
import { Optic, Schema } from "effect"
type S = { readonly items: ReadonlyArray<number> }
const _positive = Optic.id<S>()
.key("items")
.forEach((n) => n.check(Schema.isGreaterThan(0)))
const getPositive = Optic.getAll(_positive)
console.log(getPositive({ items: [1, -2, 3] }))
// Output: [1, 3]
Traversal<function (type parameter) S in Optional<in out S, in out A>.forEach<S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>): Traversal<S, B>S, function (type parameter) A in Optional<in out S, in out A>.forEach<S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>): Traversal<S, B>A>, f: (iso: Iso<A, A>) => Optional<A, B>f: (iso: Iso<A, A>(parameter) iso: {
get: (s: S) => A;
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { (this: Iso<A, A>, that: Iso<A, B>): Iso<A, B>; (this: Lens<A, A>, that: Lens<A, B>): Lens<A, B>; (this: Prism<A, A>, that: Prism<A, B>): Prism<A, B>; (this: Optional<A, A>, that: Optional<A, B>): Optional<A, B> };
modify: (f: (a: A) => A) => (s: A) => A;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<A, Exclude<A, undefined>>; (): Optional<A, Exclude<A, undefined>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
set: (a: A) => S;
}
iso: interface Iso<in out S, in out A>A lossless, reversible conversion between types S and A.
When to use
Use when you have a pair of functions that convert back and forth without losing
information (e.g. Record ↔ entries, Celsius ↔ Fahrenheit).
- You want the strongest optic that can be composed with any other.
Details
get(s) always succeeds and returns an A.
set(a) always succeeds and returns an S.
get(set(a)) === a and set(get(s)) equals s (round-trip laws).
- Extends both
Lens
and
Prism
.
Example (Converting between Celsius and Fahrenheit)
import { Optic } from "effect"
const fahrenheit = Optic.makeIso<number, number>(
(c) => c * 9 / 5 + 32,
(f) => (f - 32) * 5 / 9
)
console.log(fahrenheit.get(100))
// Output: 212
console.log(fahrenheit.set(32))
// Output: 0
Iso<function (type parameter) A in Optional<in out S, in out A>.forEach<S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>): Traversal<S, B>A, function (type parameter) A in Optional<in out S, in out A>.forEach<S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>): Traversal<S, B>A>) => interface Optional<in out S, in out A>The most general optic — both reading and writing can fail.
When to use
Use when the focus may not exist in S and writing a new A back may also
fail, for example when the source no longer matches the expected shape. This
is the base type extended by
Iso
,
Lens
,
Prism
, and
Details
getResult(s) returns Result.Success<A> or Result.Failure<string>.
replaceResult(a, s) returns Result.Success<S> or
Result.Failure<string>.
replace(a, s) returns the original s on failure (never throws).
modify(f) returns the original s on failure (never throws).
- All operations are pure; inputs are never mutated.
Example (Focusing on an optional record key)
import { Optic, Result } from "effect"
type Env = { [key: string]: string }
const _home = Optic.id<Env>().at("HOME")
console.log(Result.isSuccess(_home.getResult({ HOME: "/root" })))
// Output: true
console.log(Result.isFailure(_home.getResult({ PATH: "/bin" })))
// Output: true
// replace returns original on failure
console.log(_home.replace("/new", { PATH: "/bin" }))
// Output: { PATH: "/bin" }
Optional<function (type parameter) A in Optional<in out S, in out A>.forEach<S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>): Traversal<S, B>A, function (type parameter) B in Optional<in out S, in out A>.forEach<S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>): Traversal<S, B>B>): interface Traversal<in out S, in out A>An optic that focuses on zero or more elements of type A inside S.
When to use
Use when you want to read/update multiple elements at once (e.g. all items in
an array, or a filtered subset).
Details
- Technically
Optional<S, ReadonlyArray<A>> — the focused value is an
array of all matched elements.
- Use
.forEach() to add per-element sub-optics (filtering, drilling
deeper).
- Use
.modifyAll(f) to map a function over every focused element.
- Use
getAll
to extract all focused elements as a plain array.
Example (Traversing array elements with a filter)
import { Optic, Schema } from "effect"
type S = { readonly items: ReadonlyArray<number> }
const _positive = Optic.id<S>()
.key("items")
.forEach((n) => n.check(Schema.isGreaterThan(0)))
const getPositive = Optic.getAll(_positive)
console.log(getPositive({ items: [1, -2, 3] }))
// Output: [1, 3]
Traversal<function (type parameter) S in Optional<in out S, in out A>.forEach<S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>): Traversal<S, B>S, function (type parameter) B in Optional<in out S, in out A>.forEach<S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>): Traversal<S, B>B>
/**
* Applies a function to **every** element focused by the traversal.
*
* **Details**
*
* Available only on {@link Traversal}. Returns a function `(s: S) => S`.
* If the traversal cannot focus, the original `s` is returned unchanged.
*
* Unlike `.modify()`, which operates on the whole array, `modifyAll`
* maps `f` over each individual element.
*
* **Example** (Doubling all focused values)
*
* ```ts
* import { Optic, Schema } from "effect"
*
* type S = { readonly items: ReadonlyArray<number> }
*
* const _positive = Optic.id<S>()
* .key("items")
* .forEach((n) => n.check(Schema.isGreaterThan(0)))
*
* const doubled = _positive.modifyAll((n) => n * 2)
*
* console.log(doubled({ items: [1, -2, 3] }))
* // Output: { items: [2, -2, 6] }
* ```
*
* @see `.forEach()` — create a sub-traversal
* @see {@link getAll} — extract focused elements
*/
Optional<S, A>(this: Traversal<S, A>, f: (a: A) => A): (s: S) => SApplies a function to every element focused by the traversal.
Details
Available only on
Traversal
. Returns a function (s: S) => S.
If the traversal cannot focus, the original s is returned unchanged.
Unlike .modify(), which operates on the whole array, modifyAll
maps f over each individual element.
Example (Doubling all focused values)
import { Optic, Schema } from "effect"
type S = { readonly items: ReadonlyArray<number> }
const _positive = Optic.id<S>()
.key("items")
.forEach((n) => n.check(Schema.isGreaterThan(0)))
const doubled = _positive.modifyAll((n) => n * 2)
console.log(doubled({ items: [1, -2, 3] }))
// Output: { items: [2, -2, 6] }
modifyAll<function (type parameter) S in Optional<in out S, in out A>.modifyAll<S, A>(this: Traversal<S, A>, f: (a: A) => A): (s: S) => SS, function (type parameter) A in Optional<in out S, in out A>.modifyAll<S, A>(this: Traversal<S, A>, f: (a: A) => A): (s: S) => SA>(this: Traversal<S, A>(parameter) this: {
node: Node;
getResult: (s: S) => Result.Result<A, string>;
replace: (a: A, s: S) => S;
replaceResult: (a: A, s: S) => Result.Result<S, string>;
compose: { (this: Iso<S, ReadonlyArray<A>>, that: Iso<ReadonlyArray<A>, B>): Iso<S, B>; (this: Lens<S, ReadonlyArray<A>>, that: Lens<ReadonlyArray<A>, B>): Lens<S, B>; (this: Prism<S, ReadonlyArray<A>>, that: Prism<ReadonlyArray<A>, B>): Prism<S, B…;
modify: (f: (a: ReadonlyArray<A>) => ReadonlyArray<A>) => (s: S) => S;
key: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `key` on a union type'>): Lens<S, A[Key]>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: For…;
optionalKey: { <S, A extends object, Key extends keyof A>(this: Lens<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `optionalKey` on a union type'>): Lens<S, A[Key] | undefined>; <S, A extends object, Key extends keyof A>(this: Optional<S, A>, ke…;
check: { <S, A>(this: Prism<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Prism<S, A>; <S, A>(this: Optional<S, A>, checks_0: SchemaAST.Check<A>, ...checks: Array<SchemaAST.Check<A>>): Optional<S, A> };
refine: { <S, A, B extends A>(this: Prism<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter): Prism<S, B>; <S, A, B extends A>(this: Optional<S, A>, refinement: (a: A) => a is B, annotations?: Schema.Annotations.Filter):…;
tag: { <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(this: Prism<S, A>, tag: Tag): Prism<S, Extract<A, { readonly _tag: Tag }>>; <S, A extends { readonly _tag: SchemaAST.LiteralValue }, Tag extends A['_tag']>(t…;
at: <S, A extends object, Key extends keyof A>(this: Optional<S, A>, key: Key, ..._err: ForbidUnion<A, 'cannot use `at` on a union type'>) => Optional<S, A[Key]>;
pick: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `pick` on a union type'>): Lens<S, Pick<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
omit: { <S, A, Keys extends ReadonlyArray<keyof A>>(this: Lens<S, A>, keys: Keys, ..._err: ForbidUnion<A, 'cannot use `omit` on a union type'>): Lens<S, Omit<A, Keys[number]>>; <S, A, Keys extends ReadonlyArray<keyof A>>(this: Optional<S, A>, ke…;
notUndefined: { (): Prism<S, ReadonlyArray<A>>; (): Optional<S, ReadonlyArray<A>> };
forEach: <S, A, B>(this: Traversal<S, A>, f: (iso: Iso<A, A>) => Optional<A, B>) => Traversal<S, B>;
modifyAll: <S, A>(this: Traversal<S, A>, f: (a: A) => A) => (s: S) => S;
}
this: interface Traversal<in out S, in out A>An optic that focuses on zero or more elements of type A inside S.
When to use
Use when you want to read/update multiple elements at once (e.g. all items in
an array, or a filtered subset).
Details
- Technically
Optional<S, ReadonlyArray<A>> — the focused value is an
array of all matched elements.
- Use
.forEach() to add per-element sub-optics (filtering, drilling
deeper).
- Use
.modifyAll(f) to map a function over every focused element.
- Use
getAll
to extract all focused elements as a plain array.
Example (Traversing array elements with a filter)
import { Optic, Schema } from "effect"
type S = { readonly items: ReadonlyArray<number> }
const _positive = Optic.id<S>()
.key("items")
.forEach((n) => n.check(Schema.isGreaterThan(0)))
const getPositive = Optic.getAll(_positive)
console.log(getPositive({ items: [1, -2, 3] }))
// Output: [1, 3]
Traversal<function (type parameter) S in Optional<in out S, in out A>.modifyAll<S, A>(this: Traversal<S, A>, f: (a: A) => A): (s: S) => SS, function (type parameter) A in Optional<in out S, in out A>.modifyAll<S, A>(this: Traversal<S, A>, f: (a: A) => A): (s: S) => SA>, f: (a: A) => Af: (a: Aa: function (type parameter) A in Optional<in out S, in out A>.modifyAll<S, A>(this: Traversal<S, A>, f: (a: A) => A): (s: S) => SA) => function (type parameter) A in Optional<in out S, in out A>.modifyAll<S, A>(this: Traversal<S, A>, f: (a: A) => A): (s: S) => SA): (s: Ss: function (type parameter) S in Optional<in out S, in out A>.modifyAll<S, A>(this: Traversal<S, A>, f: (a: A) => A): (s: S) => SS) => function (type parameter) S in Optional<in out S, in out A>.modifyAll<S, A>(this: Traversal<S, A>, f: (a: A) => A): (s: S) => SS
}