Lodash _.toSafeInteger() method
What you’ll learn
- What “safe integer” means in IEEE-754 terms:
±(2⁵³ − 1). - How
_.toSafeIntegercomposes_.toIntegerwith a clamp. - Why
InfinitybecomesMAX_SAFE_INTEGERand-Infinitybecomes its negative. - How it differs from
_.toIntegerand_.toLength(different windows!).
Prerequisites
You’ve finished the _.toInteger tutorial; this method is the same truncation plus a magnitude clamp.
- You know that JavaScript numbers can’t losslessly distinguish integers above
2⁵³. - Try-it labs load lodash from the CDN.
Overview
One line of implementation: return value ? _.clamp(_.toInteger(value), −2⁵³+1, 2⁵³−1) : 0. The output is always an integer you can compare and arithmetic on without IEEE-754 surprises.
Symmetric window
Negatives allowed (±9 007 199 254 740 991).
No NaN / Infinity
Falsy and NaN → 0; ±Infinity → ±MAX_SAFE_INTEGER.
Inherits parsing
Trims whitespace; parses hex/binary/octal via _.toNumber.
Syntax
_.toSafeInteger(value) - value: the value to convert.
- Returns: a signed integer in
[−(2⁵³−1), 2⁵³−1]. NeverNaNor±Infinity.
Lodash docs baseline
The four official examples—decimal, sub-1, infinity, numeric string.
import toSafeInteger from "lodash/toSafeInteger";
console.log(
"3.2: " + toSafeInteger(3.2) + "\n" + // 3
"MIN_VALUE: " + toSafeInteger(Number.MIN_VALUE) + "\n" + // 0
"Infinity: " + toSafeInteger(Infinity) + "\n" + // 9007199254740991
"'3.2' string: " + toSafeInteger("3.2") // 3
); Clamping at ±MAX_SAFE_INTEGER
The window is symmetric. Anything past the edge gets snapped back to it—negatives included.
import toSafeInteger from "lodash/toSafeInteger";
const huge = Number.MAX_SAFE_INTEGER + 5; // already lossy as a Number
const negHuge = -Number.MAX_SAFE_INTEGER - 5;
console.log(
"MAX_SAFE_INTEGER: " + toSafeInteger(Number.MAX_SAFE_INTEGER) + "\n" + // 9007199254740991
"MAX_SAFE_INTEGER + 5: " + toSafeInteger(huge) + "\n" + // 9007199254740991
"-MAX_SAFE_INTEGER - 5: " + toSafeInteger(negHuge) + "\n" + // -9007199254740991
"-Infinity: " + toSafeInteger(-Infinity) // -9007199254740991
); Strings, nullish, & numeric prefixes
Parsing inherits from _.toNumber → _.toFinite → _.toInteger: trim, hex/binary/octal, “bad input → 0.”
import toSafeInteger from "lodash/toSafeInteger";
console.log(
"'-3.2' string: " + toSafeInteger("-3.2") + "\n" + // -3
"' 7 ' trim: " + toSafeInteger(" 7 ") + "\n" + // 7
"'0x1f' hex: " + toSafeInteger("0x1f") + "\n" + // 31
"'abc': " + toSafeInteger("abc") + "\n" + // 0
"null: " + toSafeInteger(null) + "\n" + // 0
"NaN: " + toSafeInteger(NaN) // 0
); 📋 _.toSafeInteger vs related conversions
| Input | _.toSafeInteger | _.toInteger | _.toLength |
|---|---|---|---|
3.7 | 3 | 3 | 3 |
-5 | -5 | -5 | 0 |
NaN | 0 | 0 | 0 |
Infinity | 9007199254740991 | 1.79e+308 | 4294967295 |
1e20 | 9007199254740991 | 1e+20 | 4294967295 |
-Infinity | -9007199254740991 | -1.79e+308 | 0 |
Pitfalls to avoid
Input may already be lossy
Numeric literals like 9007199254740993 can’t be represented exactly—your call site has already lost precision before _.toSafeInteger sees them. For arbitrary-precision IDs, use BigInt and strings.
Truncation toward zero
Inherits _.toInteger’s behavior. _.toSafeInteger(-1.5) is -1 (not -2). Use Math.floor if you really want floor.
BigInt throws
_.toSafeInteger(1n) raises “Cannot convert a BigInt value to a number.” Convert with Number(bigint) first if you can accept truncation.
❓ FAQ
Summary
- Purpose: guarantee an integer that JavaScript can store and compare without IEEE-754 precision loss.
- Remember: truncation toward zero, clamp to
±(2⁵³−1), falsy →0. - Next: head to Lodash _.toString() —
_.toStringwraps up the conversion family.
_.toSafeInteger’s window is ±(2⁵³ − 1) = ±9 007 199 254 740 991—the largest magnitude IEEE-754 doubles can hold without losing precision between consecutive integers. Past 2⁵³, even adding 1 can return the same number you started with.
6 people found this page helpful
