Complex Structure Arbitraries
Relevant source files
The following files were used as context for generating this wiki page:- packages/fast-check/src/arbitrary/array.ts
- packages/fast-check/src/arbitrary/object.ts
- packages/fast-check/src/arbitrary/record.ts
- packages/fast-check/src/arbitrary/tuple.ts
- packages/fast-check/src/arbitrary/set.ts
- packages/fast-check/src/arbitrary/map.ts
- website/blog/2025-12-15-whats-new-in-fast-check-4-4-0/index.md
- website/blog/2025-03-10-whats-new-in-fast-check-4-0-0/index.md
The fast-check library provides a rich set of arbitraries for generating not only primitive values but also complex, structured data. These arbitraries are fundamental for creating realistic test inputs that mirror the data structures used in modern applications, such as arrays, objects, tuples, sets, and maps. By combining these with base arbitraries, developers can effectively perform property-based testing on components that consume and produce complex data.
This document details the architecture and usage of the main arbitraries used to build complex data structures: fc.array, fc.tuple, fc.set, fc.map, fc.record, and fc.object. Each serves a distinct purpose, from generating variable-length collections to creating objects with fixed or dynamic structures.
Array Arbitrary
The array arbitrary is used to generate arrays containing elements of a specified type. It is highly configurable, allowing control over the length of the generated arrays.
Sources: packages/fast-check/src/arbitrary/array.ts
fc.array(arb, constraints)
This function creates an arbitrary that generates arrays. The elements of the array are produced by the provided arb arbitrary.
The generation process for fc.array is illustrated below.
This diagram shows that the array arbitrary first determines a valid length based on constraints and then populates an array by repeatedly calling the underlying element arbitrary.
Configuration
The behavior of fc.array can be fine-tuned using the ArrayConstraints object.
| Parameter | Type | Description |
|---|---|---|
minLength | number | The minimum number of elements in the generated array. Defaults to 0. |
maxLength | number | The maximum number of elements in the generated array. Defaults to 2147483647. |
Sources: packages/fast-check/src/arbitrary/array.ts:13-20
Tuple Arbitrary
The tuple arbitrary generates arrays with a fixed length and specific, potentially different, types at each position. This is ideal for testing functions that expect arguments or return values with a known, heterogeneous structure.
Sources: packages/fast-check/src/arbitrary/tuple.ts
fc.tuple(...arbs)
Unlike fc.array, which uses a single arbitrary for all its elements, fc.tuple accepts multiple arbitraries, one for each element in the resulting tuple.
This diagram shows fc.tuple combining three different arbitraries to produce a fixed-structure array [string, integer, boolean].
The implementation simply maps over the provided arbitraries, generates one value from each, and collects them into an array. This ensures the structure is always consistent.
Sources: packages/fast-check/src/arbitrary/tuple.ts:25-27
Set Arbitrary
The set arbitrary generates Set objects, which are collections of unique values. It ensures that all elements in the generated set are unique according to the equality semantics of a Set or a custom comparison function.
Sources: packages/fast-check/src/arbitrary/set.ts, website/blog/2025-12-15-whats-new-in-fast-check-4-4-0/index.md
fc.set(arb, constraints)
This function takes an element arbitrary arb and an optional constraints object to control the size and comparison logic of the generated Set.
Configuration
The SetConstraints object provides detailed control over the generation.
| Parameter | Type | Description |
|---|---|---|
minLength | number | Minimum number of elements. Defaults to 0. |
maxLength | number | Maximum number of elements. Defaults to 2147483647. |
compare | (a: T, b: T) => boolean or { selector?: (v: T) => unknown; comparator?: (a: unknown, b: unknown) => boolean; } | Defines how to compare elements for uniqueness. It can be a simple predicate function or an object specifying a selector to extract a comparable value and an optional comparator. |
The compare function is a powerful feature for defining uniqueness based on object properties or custom logic, rather than just reference equality.
Sources: packages/fast-check/src/arbitrary/set.ts:15-33
The generation flow involves generating an array and then filtering it to ensure uniqueness.
This diagram illustrates that fc.set leverages fc.array internally and then applies a uniqueness filter before constructing the final Set instance.
Sources: packages/fast-check/src/arbitrary/set.ts:60-63
Map Arbitrary
Introduced to generate JavaScript's native Map objects, the map arbitrary allows for the creation of key-value pairs where keys and values are generated from separate arbitraries.
Sources: packages/fast-check/src/arbitrary/map.ts, website/blog/2025-12-15-whats-new-in-fast-check-4-4-0/index.md
fc.map(keyArb, valueArb, constraints)
This function generates a Map by producing key-value pairs. It ensures key uniqueness, similar to fc.set.
Configuration
The MapConstraints object allows for size control.
| Parameter | Type | Description |
|---|---|---|
minKeys | number | Minimum number of keys in the map. Defaults to 0. |
maxKeys | number | Maximum number of keys in the map. Defaults to 2147483647. |
compareKeys | (a: K, b: K) => boolean or {...} | Defines how to compare keys for uniqueness, with the same structure as compare in fc.set. |
Sources: packages/fast-check/src/arbitrary/map.ts:15-33
Object Arbitraries
fast-check provides two distinct arbitraries for generating objects: fc.record for objects with a known, fixed set of keys, and fc.object for objects with arbitrary keys.
Record Arbitrary (Known Keys)
The record arbitrary is used to generate objects that conform to a specific shape, where keys are predefined strings and values are generated by corresponding arbitraries.
Sources: packages/fast-check/src/arbitrary/record.ts
fc.record(template, constraints)
It takes a template object where each value is an arbitrary. The output is an object with the same keys as the template, but with values generated from their respective arbitraries.
This diagram shows how a template object is transformed into a concrete instance. It also illustrates the effect of the withDeletedKeys constraint.
Configuration
The RecordConstraints object offers powerful options for testing edge cases.
| Parameter | Type | Description |
|---|---|---|
withDeletedKeys | boolean | If true, some keys from the template may be omitted from the generated object. Defaults to false. |
withObjectPrototype | boolean | If true, the generated object will have a standard Object.prototype. If false (the default since v4), it will be created with Object.create(null). |
The default behavior of creating null-prototype objects is a key feature for hardening code against prototype pollution vulnerabilities.
Sources: packages/fast-check/src/arbitrary/record.ts:19-29, website/blog/2025-03-10-whats-new-in-fast-check-4-0-0/index.md
Object Arbitrary (Arbitrary Keys)
The object arbitrary generates plain JavaScript objects where both the keys and values are generated from arbitraries. This is useful for testing dictionary-like structures or code that handles dynamic object shapes.
Sources: packages/fast-check/src/arbitrary/object.ts
fc.object(constraints)
This function generates objects based on a set of constraints that define the arbitraries for keys and values, as well as size limits.
Configuration
The ObjectConstraints object provides comprehensive control over the generated objects.
| Parameter | Type | Description |
|---|---|---|
key | Arbitrary<string> | Arbitrary for generating keys. Defaults to fc.string(). |
values | Arbitrary<any> | Arbitrary for generating values. Defaults to fc.jsonValue(). |
maxKeys | number | The maximum number of keys in the generated object. |
minKeys | number | The minimum number of keys in the generated object. |
withObjectPrototype | boolean | If true, create objects with Object.prototype. Defaults to false. |
Sources: packages/fast-check/src/arbitrary/object.ts:14-34
Conclusion
The complex structure arbitraries are a cornerstone of fast-check, providing the necessary tools to generate realistic and varied data for property-based testing. By combining array, tuple, set, map, record, and object arbitraries, developers can model almost any data structure their application might encounter. The rich configuration options, such as size constraints and the ability to generate null-prototype objects or omit keys, further empower developers to uncover subtle bugs and edge cases that might be missed with traditional example-based testing.