Array.flat() & Array.flatMap()
debt(d3/e1/b1/t5)
Closest to 'default linter catches the common case' (d3). The detection_hints list ESLint as the tool, and the code_pattern 'reduce.*concat|[].concat' is a straightforward pattern ESLint rules can flag, making the misuse detectable with standard linting setup.
Closest to 'one-line patch or single-call swap' (e1). The quick_fix explicitly describes simple one-to-one replacements: reduce-concat patterns become flatMap(), [].concat(...arr) becomes arr.flat(). Each is a direct single-call substitution.
Closest to 'minimal commitment' (b1). This is a utility array method choice localised to individual call sites. It applies to web and cli contexts but imposes no architectural weight; switching or not using it has no gravitational pull on the rest of the codebase.
Closest to 'notable trap' (t5). The misconception field directly states the canonical wrong belief: developers expect flatMap() to flatten all levels, but it only flattens one level. This is a documented gotcha that many developers encounter, aligning with the t5 anchor of a well-known but non-obvious surprise.
TL;DR
Explanation
arr.flat() flattens one level by default. arr.flat(Infinity) flattens completely. arr.flat(2) flattens 2 levels. arr.flatMap(fn) is equivalent to arr.map(fn).flat(1) but more efficient. flatMap use cases: expanding one item into multiple (expanding tags into all tag instances), filtering and transforming (return [] to skip, return [item] or [a, b] to keep/expand). flat() replaces manual reduce-concat patterns. Both are ES2019 — use polyfills for IE11 (or Babel).
Watch Out
Common Misconception
Why It Matters
Common Mistakes
- Using flatMap() expecting deep flattening — only one level.
- Not knowing flat() without arguments flattens only 1 level.
- Using reduce + concat instead of flat()/flatMap() — verbose and slow.
Code Examples
// Verbose reduce-concat:
const tags = posts.reduce((acc, post) => acc.concat(post.tags), []);
// Manual flat:
const nested = [[1,2],[3,4]];
const flat = [].concat(...nested);
const tags = posts.flatMap(post => post.tags);
// Filter + transform in one pass:
const active = items.flatMap(item =>
item.active ? [{ ...item, label: item.name.toUpperCase() }] : []
);
// Deep flatten:
const deep = nested.flat(Infinity);