Skip to main content

Command Palette

Search for a command to run...

JavaScript Type Conversions

Updated
7 min read
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 clarity

  • Be aware of falsy values: false, 0, "", null, undefined, NaN

  • Empty arrays and objects are truthy

  • Use === instead of == to avoid unexpected coercion

  • Validate and handle edge cases like NaN, null, and undefined

  • Choose the right method for the job: parseInt() for integers, parseFloat() for decimals

  • Test your conversions thoroughly, especially with user input

Master these conversions, and you'll write more robust, predictable JavaScript code!