JavaScript Type Conversions

Type conversion (also known as type coercion) is one of JavaScript's most powerful yet often misunderstood features. Whether you're converting strings to numbers, booleans to integers, or arrays to strings, understanding these conversions will make you a more effective JavaScript developer.
String to Number Conversions
The Unary Plus Operator (+)
The fastest and most concise way to convert a string to a number:
+"42" // 42
+"3.14" // 3.14
+"-10" // -10
+"0xFF" // 255 (hex notation works!)
Watch out for edge cases:
+"123abc" // NaN
+"" // 0 (empty string becomes 0)
+" " // 0 (whitespace becomes 0)
The Double Bitwise NOT (~~)
Great for converting to integers, as it truncates decimals:
~~"42" // 42
~~"3.14" // 3 (truncates decimal)
~~"-10" // -10
Important difference:
+"123abc" // NaN
~~"123abc" // 0 (returns 0 instead of NaN)
Number() Constructor
More explicit and readable:
Number("42") // 42
Number("3.14") // 3.14
Number("") // 0
Number("abc") // NaN
parseInt() and parseFloat()
The classic methods, especially useful for strings with mixed content:
parseInt("42") // 42
parseInt("42px") // 42 (stops at first non-digit)
parseInt("3.14") // 3 (always returns integer)
parseFloat("3.14") // 3.14
parseFloat("3.14px") // 3.14
Pro tip: Always specify the radix with parseInt:
parseInt("10", 10) // 10 (decimal)
parseInt("10", 2) // 2 (binary)
parseInt("FF", 16) // 255 (hexadecimal)
Arithmetic Tricks
Multiplication and subtraction force type conversion:
"42" * 1 // 42
"3.14" * 1 // 3.14
"42" - 0 // 42
"100" - 20 // 80
Number to String Conversions
String Concatenation
The simplest approach:
42 + "" // "42"
3.14 + "" // "3.14"
(1 + 2) + "" // "3"
Template Literals
Modern and readable:
`${42}` // "42"
`${3.14}` // "3.14"
`Value: ${100}` // "Value: 100"
String() Constructor
Explicit conversion:
String(42) // "42"
String(3.14) // "3.14"
String(null) // "null"
String(undefined) // "undefined"
toString() Method
Offers base conversion options:
(42).toString() // "42"
(255).toString(16) // "ff" (hexadecimal)
(8).toString(2) // "1000" (binary)
(255).toString(8) // "377" (octal)
Formatting Methods
For precise decimal control:
(3.14159).toFixed(2) // "3.14"
(42).toFixed(2) // "42.00"
(1234).toExponential() // "1.234e+3"
(123.456).toPrecision(4) // "123.5"
Boolean Conversions
To Boolean: The Double NOT (!!)
The standard way to convert any value to boolean:
!!"hello" // true
!!1 // true
!!0 // false
!!"" // false
!!null // false
!!undefined // false
Important: Arrays and objects are always truthy:
!![] // true (empty array is truthy!)
!!{} // true (empty object is truthy!)
!!" " // true (non-empty string)
Boolean() Constructor
More explicit alternative:
Boolean("hello") // true
Boolean(0) // false
Boolean([]) // true
From Boolean to Other Types
Converting booleans to numbers:
true + 0 // 1
false + 0 // 0
+true // 1
+false // 0
Number(true) // 1
Number(false) // 0
Converting booleans to strings:
true + "" // "true"
false + "" // "false"
String(true) // "true"
`${false}` // "false"
Array and String Conversions
Array to String
Using join():
[1, 2, 3].join() // "1,2,3"
[1, 2, 3].join("") // "123"
[1, 2, 3].join("-") // "1-2-3"
["a", "b", "c"].join(" ")// "a b c"
Quick conversion:
[1, 2, 3].toString() // "1,2,3"
[1, 2, 3] + "" // "1,2,3"
`${[1, 2, 3]}` // "1,2,3"
String to Array
Multiple approaches:
// Split method
"hello".split("") // ['h', 'e', 'l', 'l', 'o']
"a,b,c".split(",") // ['a', 'b', 'c']
"one two three".split(" ") // ['one', 'two', 'three']
// Spread operator (ES6+)
[..."hello"] // ['h', 'e', 'l', 'l', 'o']
[..."abc"] // ['a', 'b', 'c']
// Array.from()
Array.from("hello") // ['h', 'e', 'l', 'l', 'o']
Object Conversions
Object to Array
const obj = {a: 1, b: 2, c: 3};
Object.keys(obj) // ['a', 'b', 'c']
Object.values(obj) // [1, 2, 3]
Object.entries(obj) // [['a', 1], ['b', 2], ['c', 3]]
Array to Object
// From entries
Object.fromEntries([['a', 1], ['b', 2]])
// Result: {a: 1, b: 2}
// Using reduce
['a', 'b', 'c'].reduce((acc, val, i) => ({...acc, [val]: i}), {})
// Result: {a: 0, b: 1, c: 2}
// From keys with default value
Object.fromEntries(['a', 'b', 'c'].map(k => [k, 0]))
// Result: {a: 0, b: 0, c: 0}
JSON Conversions
const obj = {name: "Alice", age: 25};
// Object to JSON string
JSON.stringify(obj)
// '{"name":"Alice","age":25}'
JSON.stringify(obj, null, 2)
// Formatted with 2-space indentation
// JSON string to Object
JSON.parse('{"name":"Alice","age":25}')
// {name: 'Alice', age: 25}
Special Cases and Gotchas
Null and Undefined Handling
Default values with nullish coalescing:
null ?? "default" // "default"
undefined ?? "default" // "default"
0 ?? "default" // 0 (not null/undefined)
"" ?? "default" // "" (not null/undefined)
Default values with logical OR:
null || "default" // "default"
0 || "default" // "default" (0 is falsy)
"" || "default" // "default" (empty string is falsy)
false || "default" // "default"
Weird Coercions You Should Know
These might surprise you:
[] + [] // "" (empty string!)
[] + {} // "[object Object]"
{} + [] // 0 (in some contexts)
[] == false // true
"0" == 0 // true (loose equality coerces)
"0" === 0 // false (strict equality doesn't)
null == undefined // true
null === undefined // false
Math Operations
Addition vs other operators:
"5" + 3 // "53" (concatenation)
"5" - 3 // 2 (conversion)
"5" * "2" // 10 (both convert)
"10" / "2" // 5 (both convert)
Date Conversions
const date = new Date("2024-01-15");
// Date to timestamp
+date // 1705276800000
date.getTime() // 1705276800000
// Date to string
date.toISOString() // "2024-01-15T00:00:00.000Z"
date.toLocaleDateString()// "1/15/2024"
// Timestamp to date
new Date(1705276800000) // Mon Jan 15 2024
Number Base Conversions
// Decimal to other bases
(255).toString(16) // "ff" (hex)
(255).toString(2) // "11111111" (binary)
(255).toString(8) // "377" (octal)
// Other bases to decimal
parseInt("ff", 16) // 255
parseInt("11111111", 2) // 255
parseInt("377", 8) // 255
// Formatting
(255).toString(16).toUpperCase() // "FF"
(10).toString(2).padStart(8, "0") // "00001010"
Best Practices
1. Be Explicit When It Matters
For production code, explicit conversions are often clearer:
// Good
Number(userInput)
String(value)
Boolean(condition)
// Clever but less clear
+userInput
value + ""
!!condition
2. Use Strict Equality
Always use === instead of == to avoid unexpected coercion:
// Avoid
if (value == 0) { } // Could match "", [], false
// Prefer
if (value === 0) { } // Only matches 0
3. Handle NaN Properly
// Wrong way
value === NaN // Always false (NaN !== NaN)
// Right way
Number.isNaN(value) // true only for NaN
isNaN(value) // true if value converts to NaN
4. Validate Before Converting
// Safe conversion function
const toNumber = (str) => {
const num = +str;
return isNaN(num) ? 0 : num;
};
toNumber("42") // 42
toNumber("abc") // 0 (safe fallback)
5. Choose the Right Method
For integers from strings: Use parseInt() with radix
parseInt("42", 10) // Always specify base
For floats from strings: Use parseFloat() or Number()
parseFloat("3.14")
Number("3.14")
For formatting numbers: Use toFixed(), toPrecision()
(3.14159).toFixed(2) // "3.14"
For boolean checks: Use Boolean() or !!
if (Boolean(value)) { }
if (!!value) { }
Practical Examples
CSV String to Number Array
"1,2,3,4,5".split(",").map(Number)
// [1, 2, 3, 4, 5]
RGB to Hex Color
const rgbToHex = (r, g, b) =>
"#" + [r, g, b].map(x => x.toString(16).padStart(2, "0")).join("");
rgbToHex(255, 0, 128) // "#ff0080"
Hex to RGB Color
const hexToRgb = hex =>
hex.match(/[A-Fa-f0-9]{2}/g).map(x => parseInt(x, 16));
hexToRgb("#ff0080") // [255, 0, 128]
Query Parameters to Object
const params = "?name=Alice&age=25";
Object.fromEntries(new URLSearchParams(params))
// {name: 'Alice', age: '25'}
Safe Integer Conversion
const toInt = (value, defaultValue = 0) => {
const num = parseInt(value, 10);
return isNaN(num) ? defaultValue : num;
};
toInt("42") // 42
toInt("abc") // 0
toInt("abc", -1) // -1
Conclusion
JavaScript's type conversion system is flexible and powerful, but it requires understanding to use effectively. Remember these key points:
Use explicit conversions (
Number(),String(),Boolean()) for clarityBe aware of falsy values:
false,0,"",null,undefined,NaNEmpty arrays and objects are truthy
Use
===instead of==to avoid unexpected coercionValidate and handle edge cases like
NaN,null, andundefinedChoose the right method for the job:
parseInt()for integers,parseFloat()for decimalsTest your conversions thoroughly, especially with user input
Master these conversions, and you'll write more robust, predictable JavaScript code!



