Skip to Content
  • Website
Codsen
  • Home
  • Open Source
  • Articles
  • About

prevOpen Source→object-boolean-combinationsnext

object-boolean-combinations6.3.2

Consumes a defaults object with booleans, generates all possible variations of it

Downloads per monthChangelogMIT Licenselibera manifesto
  • the top
  • Installation
  • Quick Take
  • Examples
  • PURPOSE
  • API — COMBINATIONS(…
  • OVERRIDES
  • KEY BEHAVIOR
  • API — TYPES
  • API — VERSION
  • Changelog

Permalink to InstallationInstallation

Permalink to Quick TakeQuick Take

Permalink to ExamplesExamples

  • Generate the one possible combination for an empty key set
  • Hold selected keys constant while varying the others
  • Fixed nested values are shared between generated rows

Purpose

object-boolean-combinations generates every supported true-or-false assignment for an object’s own enumerable string keys. Input values are ignored; only the keys define the boolean dimensions. Each unpinned key doubles the number of returned rows.

For example, 12 unpinned keys produce 2^12 = 4096 rows. Six unpinned keys produce 2^6 = 64 rows.

Use this package when you need the raw Cartesian product of a set of key names. If you have a defaults object and want to vary only its boolean-valued properties while carrying other values into every test case, use test-mixer.

API — combinations()

The main function combinations() is imported like this:

declare function combinations<
  Input extends UnknownValueObject,
  Override extends UnknownValueObject | undefined = undefined,
>(input: Input, Override?: Override): Combination<Input, Override>[];
Input argumentTypeRequiredDescription
input
Type: UnknownValueObject
inputUnknownValueObjectYesSupplies the own enumerable string keys to vary. Its property values are not read.
Override
Type: UnknownValueObject | undefined
OverrideUnknownValueObject | undefinedNoPins matching input keys to fixed values. Omit it or pass undefined to vary every input key. Extra override keys are ignored.

The required input container must be a plain object. The override must also be a plain object when present; omit it or pass undefined to use the default. Arrays, dates, maps, sets, functions, null, and primitive values are rejected when supplied as either outer container.

If n input keys remain unpinned, combinations() returns 2^n plain objects. The first unpinned key toggles fastest. An empty input returns [{}].

Without an override, every returned value is boolean. With an override, matching keys retain the override value and its TypeScript type; all other input keys are boolean. Extra override keys never enter the result.

Eager safety limit

combinations() returns at most 16,384 rows, equivalent to 14 unpinned keys. A larger request throws before allocating the result array. Pin enough keys to bring the free-key count to 14 or fewer, or use a different strategy that does not retain the complete Cartesian product.

The limit applies after matching overrides. For example, a 15-key input succeeds when the override pins at least one of those keys.

Overrides

An override fixes selected keys while the other keys continue to vary:

import { strict as assert } from "node:assert";

import { combinations } from "object-boolean-combinations";

const compression = { level: 9 };
const rows = combinations(
  { cache: false, compress: false, sourceMap: false },
  { compress: compression },
);

assert.deepEqual(rows, [
  { cache: false, sourceMap: false, compress: { level: 9 } },
  { cache: true, sourceMap: false, compress: { level: 9 } },
  { cache: false, sourceMap: true, compress: { level: 9 } },
  { cache: true, sourceMap: true, compress: { level: 9 } },
]);

The override above removes one boolean dimension, reducing the output from 2^3 = 8 rows to 2^(3-1) = 4 rows.

Override values can be primitives, functions, arrays, dates, maps, sets, or cyclic object graphs. Cloneable objects and collections are detached from the caller once per call. Functions retain their identity. The resulting fixed value is then shared by every row:

assert.notEqual(rows[0].compress, compression);
assert.equal(rows[0].compress, rows[1].compress);

rows[0].compress.level = 7;
assert.equal(rows[1].compress.level, 7);
assert.equal(compression.level, 9);

Mutating a nested fixed value through one row therefore affects its sibling rows, but it does not affect the caller’s cloneable source object. This shared-row contract avoids duplicating a fixed object graph for every row in an already exponential result.

Key behavior

Only own enumerable string keys participate. Inherited, non-enumerable, and symbol keys are ignored. The special string key __proto__ is treated as an ordinary own data property; it does not change a returned object’s prototype.

For ordinary string keys, each row adds unpinned keys in input order, followed by pinned keys in override order. The order of the rows is stable, with the first unpinned key changing on every row.

API — types

This package exports the following TypeScript types:

TypeDescription
UnknownValueObject
Type: UnknownValueObject
UnknownValueObjectA string-keyed object whose property values can have any supported type.
BoolObj
Type: BoolObj
BoolObjA broad string-to-boolean row type for no-override use when the exact input keys are not known.
BooleanCombination<Input>
Type: BooleanCombination<Input>
BooleanCombination<Input>Maps each own string or numeric key from Input to boolean.
Combination<Input, Override>
Type: Combination<Input, Override>
Combination<Input, Override>Maps matching keys to their override value types and every other input key to boolean.
import type {
  BooleanCombination,
  BoolObj,
  Combination,
  UnknownValueObject,
} from "object-boolean-combinations";

API — version

You can import version:

Permalink to changelogChangelog

Open Changelog
↑ back to top
prev next

Copyright

All rights reserved © Roy Revelt 2026
All our open source packages are under MIT licenceopens in a new tab

Activities

🐛 See a bug? Raise an issueopens in a new tab
💘 Check out the Indiewebopens in a new tab and Libera manifestoopens in a new tab