Choose Between Array Tuple Record Map and Set

TypeScript gives you several typed collection types. Learn how to choose between Array, Tuple, Record, Map, and Set based on your data's shape, key type, and access patterns.

6 min read

To choose between Array, Tuple, Record, Map, and Set in TypeScript, look at your data's shape and access pattern. Each of these five typed collection types is designed for a different kind of data, and choosing the right one makes your types more precise and your code easier to understand.

This article compares them side by side so you can pick the right structure for each situation without second-guessing.

Quick comparison

The table below summarises each type's key characteristics. Use it as a reference when deciding which type fits your data:

FeatureArrayTupleRecordMapSet
Key typeNumeric indexNumeric indexString literalAny typeNone (values only)
LengthVariableFixedFixed (known keys)VariableVariable
Element typesOne type for allDifferent per positionOne value typeSeparate key/value typesOne type for all
DuplicatesAllowedAllowedOverwritesOverwritesForbidden
Runtime presenceJavaScript ArrayJavaScript ArrayPlain objectJavaScript MapJavaScript Set
Order guaranteeYesYesInsertion (modern JS)InsertionInsertion

The runtime presence row matters because it affects what you can pass across API boundaries. Arrays, Maps, and Sets are real JavaScript objects, while tuples are just arrays at runtime and records are just plain objects.

When to use an Array

Use an Array when you have an ordered list of similar items with no fixed length requirement. Arrays are the default collection type for most use cases, and reaching for one first is usually the right instinct.

The element type describes every element in the array. If you need mixed types, use a union as the element type. Arrays support index-based access, iteration, and the full set of transformation methods, including map, filter, and reduce.

Common use cases include lists of search results, collections of user-generated items, ordered queues, and any data that arrives as a JSON array from an API.

When to use a Tuple

Use a Tuple when you have a small, fixed number of elements where each position has a distinct meaning. The classic example is a key-value pair represented as [string, number].

Tuples enforce exact length and per-position types at compile time. Accessing an out-of-bounds index is a compiler error. This makes tuples ideal for convention-based patterns where the meaning of each position is obvious from context.

Common use cases include React's useState return value, coordinate pairs, CSV rows with a known column order, and function parameter lists captured as data. For more on tuple syntax and labelled tuples, see tuples in TypeScript explained.

When to use a Record

Use a Record when you have a fixed set of string keys known at compile time, each mapping to the same value type. A Record type is written as Record with the key union and the value type in angle brackets.

Records enforce that all declared keys are present when you create the object. Missing a key is a compiler error. Adding an unexpected key is also an error through excess property checking.

typescripttypescript
type Theme = Record<"background" | "text" | "accent", string>;
 
let light: Theme = {
  background: "#ffffff",
  text: "#000000",
  accent: "#0066cc",
};

Every key must be present. If you omit accent, the compiler reports a missing property. Records are best for configuration objects, theme definitions, enum-like mappings, and any object where the key set is known and fixed at compile time.

When to use a Map

Use a Map when you need a key-value store with keys that are not limited to strings, or when the key set changes dynamically at runtime. Map keys can be objects, numbers, or even other Maps.

Maps also preserve insertion order and provide a size property that updates as entries are added or removed. Unlike objects, Maps have a clear separation between data properties and inherited prototype methods.

Common use cases include caches with object keys, event listener registries, DOM node metadata storage, and any scenario where keys are generated at runtime rather than fixed at compile time. For details on Map type syntax and operations, see map and set types in TypeScript.

When to use a Set

Use a Set when uniqueness is the primary constraint and you need fast membership testing. A Set automatically prevents duplicate values and provides constant-time has and delete operations, which is far faster than scanning an array with includes.

Unlike an Array, a Set has no index-based access, so it is not the right choice when order and position matter.

Sets are ideal for tracking seen items during iteration, building deduplicated lists from user input, and maintaining collections where "does this exist" is the most frequent operation rather than ordered access.

Common use cases include tracking visited nodes in a graph traversal, collecting unique tags from user-generated content, and maintaining active connection IDs where duplicates must be rejected.

Decision flowchart

When you are unsure which type to pick, walk through these questions in order: whether you need key-value access, whether positions have distinct types, and whether uniqueness is the main constraint.

Choosing a TypeScript collection type

Start at the top: no key-value access and no fixed per-position shape means a plain Array, while a small group with a distinct type per position means a Tuple. When key-value access is required, string literal keys known at compile time point to a Record, and dynamic or non-string keys point to a Map.

Each type has a clear strength: Arrays for ordered lists, Tuples for fixed-format groups, Records for compile-time-known key-value stores, Maps for dynamic key-value stores, and Sets for unique-value collections. Use the type that matches your data's shape, not the one you reach for by habit.

Rune AI

Rune AI

Key Insights

  • Array: ordered, homogeneous, index-accessible list with any length.
  • Tuple: fixed-length array with per-position types for small convention-based groups.
  • Record: key-value type with compile-time-known string literal keys.
  • Map: key-value type with any key type and dynamic size.
  • Set: unique-value collection with fast membership testing.
RunePowered by Rune AI

Frequently Asked Questions

When should I use Record instead of Map?

Use Record when your keys are string literals known at compile time and you want the compiler to check that all keys are present. Use Map when keys are dynamic, non-string, or the size changes frequently at runtime.

Is Tuple always better than Array when I know the exact length?

Not always. Tuples work best for small, convention-based groups where each position has a distinct meaning. Arrays are better for homogeneous lists of any length, even when the length happens to be known.

Does Set have better performance than Array for checking membership?

Yes. Set has constant-time has and delete operations, while Array requires linear-time includes and indexOf. For large collections where membership testing is frequent, Set is significantly faster.

Conclusion

Each collection type solves a different problem. Arrays handle ordered lists. Tuples handle small fixed-format groups. Records handle compile-time-known key-value maps. Maps handle dynamic key-value stores with any key type. Sets handle unique-value collections with fast membership checks. Pick the type that matches your data's shape and access patterns, not the one you reach for by habit.