Skip to content
Effect 4.0 is here. One ecosystem. Zero dependencies.

Tuple

This module provides utility functions for working with tuples in TypeScript.

15 exports Since v2.0.0 Source

Combinators

Given a tuple of Equivalences returns a new Equivalence that compares values of a tuple by applying each Equivalence to the corresponding element of the tuple.

Signature

declare const getEquivalence: <T extends ReadonlyArray<Equivalence.Equivalence<any>>>(...isEquivalents: T) => Equivalence.Equivalence<Readonly<{ [I in keyof T]: [T[I]] extends [Equivalence.Equivalence<infer A>] ? A : never }>>
Since v2.0.0

This function creates and returns a new Order for a tuple of values based on the given Orders for each element in the tuple. The returned Order compares two tuples of the same type by applying the corresponding Order to each element in the tuple. It is useful when you need to compare two tuples of the same type and you have a specific way of comparing each element of the tuple.

Signature

declare const getOrder: <T extends ReadonlyArray<order.Order<any>>>(...elements: T) => order.Order<{ [I in keyof T]: [T[I]] extends [order.Order<infer A>] ? A : never }>

Concatenating

Appends an element to the end of a tuple.

Signature

declare const appendElement: {
<B>(that: B): <A extends readonly Array<unknown>>(self: A) => [...Array<A>, B];
<A extends readonly Array<unknown>, B>(self: A, that: B): [...Array<A>, B];
}

Constructors

Since v2.0.0

Constructs a new tuple from the provided values.

Signature

declare function make<A extends readonly Array<any>>(...elements: A): A

Example

import * as assert from "node:assert"
import { make } from "effect/Tuple"
assert.deepStrictEqual(make(1, 'hello', true), [1, 'hello', true])

Getters

Since v3.4.0

Retrieves the element at a specified index from a tuple.

Signature

declare const at: {
<N extends number>(index: N): <A extends readonly Array<unknown>>(self: A) => A[N];
<A extends readonly Array<unknown>, N extends number>(self: A, index: N): A[N];
}

Example

import * as assert from "node:assert"
import { Tuple } from "effect"
assert.deepStrictEqual(Tuple.at([1, 'hello', true], 1), 'hello')
Since v2.0.0

Return the first element from a tuple with two elements.

Signature

declare function getFirst<L, R>(self: readonly [L, R]): L

Example

import * as assert from "node:assert"
import { getFirst } from "effect/Tuple"
assert.deepStrictEqual(getFirst(["hello", 42]), "hello")

Return the second element from a tuple with two elements.

Signature

declare function getSecond<L, R>(self: readonly [L, R]): R

Example

import * as assert from "node:assert"
import { getSecond } from "effect/Tuple"
assert.deepStrictEqual(getSecond(["hello", 42]), 42)

Guards

A refinement that checks if a ReadonlyArray<T> is a tuple with exactly N elements. If the check is successful, the type is narrowed to TupleOf<N, T>.

Signature

declare const isTupleOf: {
<N extends number>(n: N): <T>(self: readonly Array<T>) => self is TupleOf<N, T>;
<T, N extends number>(self: readonly Array<T>, n: N): self is TupleOf<N, T>;
}

Example

import * as assert from "node:assert"
import { isTupleOf } from "effect/Predicate"
const isTupleOf3 = isTupleOf(3)
assert.strictEqual(isTupleOf3([1, 2, 3]), true);
assert.strictEqual(isTupleOf3([1, 2]), false);
const arr: number[] = [1, 2, 3];
if (isTupleOf(arr, 3)) {
// The type of arr is now [number, number, number]
const [a, b, c] = arr;
assert.deepStrictEqual([a, b, c], [1, 2, 3])
}

A refinement that checks if a ReadonlyArray<T> is a tuple with at least N elements. If the check is successful, the type is narrowed to TupleOfAtLeast<N, T>.

Signature

declare const isTupleOfAtLeast: {
<N extends number>(n: N): <T>(self: readonly Array<T>) => self is [...Array<TupleOf<N, T>>, ...Array<T>];
<T, N extends number>(self: readonly Array<T>, n: N): self is [...Array<TupleOf<N, T>>, ...Array<T>];
}

Example

import * as assert from "node:assert"
import { isTupleOfAtLeast } from "effect/Predicate"
const isTupleOfAtLeast3 = isTupleOfAtLeast(3)
assert.strictEqual(isTupleOfAtLeast3([1, 2, 3]), true);
assert.strictEqual(isTupleOfAtLeast3([1, 2, 3, 4]), true);
assert.strictEqual(isTupleOfAtLeast3([1, 2]), false);
const arr: number[] = [1, 2, 3, 4];
if (isTupleOfAtLeast(arr, 3)) {
// The type of arr is now [number, number, number, ...number[]]
const [a, b, c] = arr;
assert.deepStrictEqual([a, b, c], [1, 2, 3])
}

Mapping

Since v3.9.0

Transforms each element of tuple using the given function, treating tuple homomorphically

Signature

declare const map: {
<T extends readonly Array<any> | [], B>(fn: (element: T[number]) => B): (self: T) => TupleOf<T["length"], B>;
<B, T extends readonly Array<any> | []>(self: T, fn: (element: T[number]) => B): TupleOf<T["length"], B>;
}

Example

import * as assert from "node:assert"
import { pipe, Tuple } from "effect"
const result = pipe(
["a", 1, false] as const,
Tuple.map((el) => el.toString().toUpperCase())
)
assert.deepStrictEqual(result, ['A', '1', 'FALSE'])
Since v2.0.0

Transforms both elements of a tuple with two elements using the given functions.

Signature

declare const mapBoth: {
<L1, L2, R1, R2>(options: {
readonly onFirst: (e: L1) => L2;
readonly onSecond: (a: R1) => R2;
}): (self: readonly [L1, R1]) => [L2, R2];
<L1, R1, L2, R2>(self: readonly [L1, R1], options: {
readonly onFirst: (e: L1) => L2;
readonly onSecond: (a: R1) => R2;
}): [L2, R2];
}

Example

import * as assert from "node:assert"
import { mapBoth } from "effect/Tuple"
assert.deepStrictEqual(
mapBoth(["hello", 42], { onFirst: s => s.toUpperCase(), onSecond: n => n.toString() }),
["HELLO", "42"]
)
Since v2.0.0

Transforms the first component of a tuple with two elements using a given function.

Signature

declare const mapFirst: {
<L1, L2>(f: (left: L1) => L2): <R>(self: readonly [L1, R]) => [L2, R];
<L1, R, L2>(self: readonly [L1, R], f: (left: L1) => L2): [L2, R];
}

Example

import * as assert from "node:assert"
import { mapFirst } from "effect/Tuple"
assert.deepStrictEqual(
mapFirst(["hello", 42], s => s.toUpperCase()),
["HELLO", 42]
)

Transforms the second component of a tuple with two elements using a given function.

Signature

declare const mapSecond: {
<R1, R2>(f: (right: R1) => R2): <L>(self: readonly [L, R1]) => [L, R2];
<L, R1, R2>(self: readonly [L, R1], f: (right: R1) => R2): [L, R2];
}

Example

import * as assert from "node:assert"
import { mapSecond } from "effect/Tuple"
assert.deepStrictEqual(
mapSecond(["hello", 42], n => n.toString()),
["hello", "42"]
)

Other

Since v2.0.0

Swaps the elements of a tuple with two elements.

Signature

declare function swap<L, R>(self: readonly [L, R]): [R, L]

Example

import * as assert from "node:assert"
import { swap } from "effect/Tuple"
assert.deepStrictEqual(swap(["hello", 42]), [42, "hello"])

Type Lambdas

Since v2.0.0

Signature

interface TupleTypeLambda extends TypeLambda {
readonly type: [unknown, unknown];
}