Lodash Handling Boolean Primitives in Object Mapping
This article examines how the Lodash JavaScript library handles type
errors and evaluation when a boolean primitive (true or
false) is passed into strict object mapping methods such as
_.mapValues or _.mapKeys. Instead of raising a
runtime TypeError, Lodash utilizes defensive coercion and
internal key-retrieval mechanisms that fail silently, treating boolean
primitives as empty objects and returning an empty result.
Defensive Coercion Over Runtime Exceptions
In native JavaScript, attempting to access properties or iterate over
incompatible types can sometimes result in runtime exceptions. Lodash,
however, is built around defensive programming principles. When an
explicit boolean primitive is supplied to an object mapping method—such
as _.mapValues(true, iteratee)—Lodash does not throw a
TypeError.
Instead of strictly validating that the input is a plain object,
Lodash attempts to extract the collection's enumerable keys using
internal utilities equivalent to Object.keys().
The Evaluation of Boolean Primitives
When a boolean primitive is evaluated:
- Object Conversion: The primitive is conceptually
wrapped via
Object(value). In JavaScript,Object(true)yields a[Boolean: true]wrapper object. - Key Extraction: Lodash queries the own enumerable string-keyed properties of the target. A boolean wrapper object has no own enumerable properties; its internal value is non-enumerable.
- Empty Property List: Because the list of enumerable
properties evaluates to empty (
[]), the mapping loop completes zero iterations. - Iteratee Bypass: The provided mapping function (iteratee) is never invoked, preventing any internal mapping logic or secondary errors from running.
const _ = require('lodash');
// Evaluating an explicitly provided boolean primitive
const resultValues = _.mapValues(true, (val) => val);
const resultKeys = _.mapKeys(false, (val, key) => key);
console.log(resultValues); // Output: {}
console.log(resultKeys); // Output: {}TypeScript and Strict Type Checking
While Lodash’s runtime implementation absorbs the boolean primitive without throwing an error, type safety behaves differently at compile time.
When using Lodash with TypeScript definitions
(@types/lodash), methods like _.mapValues
define their primary parameter as a collection or an object
dictionary:
mapValues<T>(object: Dictionary<T> | NumericDictionary<T> | null | undefined, ...): Dictionary<any>;Passing an explicit boolean primitive (true or
false) in a TypeScript environment triggers a compile-time
type error:
Argument of type 'boolean' is not assignable to parameter of type 'object | null | undefined'.
At compile time, strict type definitions flag the mismatch. At
runtime, Lodash bypasses the error entirely, returning a newly
allocated, empty object ({}).