DocsHub
Basics

JavaScript Type Coercion

Learn how JavaScript automatically converts types behind the scenes — and how to stay in control of it.

Type Coercion

JavaScript is a loosely typed language. You don't declare types — and when you mix different types together, JavaScript doesn't throw an error. Instead, it quietly converts one type to another and moves on.

This automatic conversion is called type coercion.

console.log("5" + 1);  // "51" — not 6
console.log("5" - 1);  // 4   — not an error

Both lines mix a string and a number. JavaScript handles both — but in completely different ways. Understanding why is what this topic is about.


Two Kinds of Coercion

Implicit Coercion — JavaScript does it automatically

This happens without you asking for it. JavaScript decides to convert a type on its own.

console.log("10" - 5);   // 5   — string "10" converted to number
console.log("10" * 2);   // 20  — same
console.log(true + 1);   // 2   — true converted to 1
console.log(false + 1);  // 1   — false converted to 0

Explicit Coercion — you do it on purpose

You use built-in functions to intentionally convert a type.

let input = "42";

let num = Number(input);   // "42" → 42
let str = String(42);      // 42 → "42"
let bool = Boolean(0);     // 0 → false

Explicit coercion is always better — you are in control, the intent is clear, and there are no surprises.


String Coercion — the + trap

The + operator is the trickiest one. It does two jobs — addition for numbers and concatenation for strings. When it sees a string, it always chooses concatenation.

console.log(10 + 20);       // 30    — both numbers, addition
console.log("10" + 20);     // "1020" — string present, concatenation
console.log(10 + "20");     // "1020" — same
console.log("10" + "20");   // "1020" — same

Order matters too when you chain operations:

console.log(10 + 20 + "px"); // "30px"  — adds 10+20 first, then joins "px"
console.log("px" + 10 + 20); // "px1020" — "px"+10 happens first, then +"20"

JavaScript reads left to right. Once a string appears, everything after it gets concatenated — not added.

This is the most common beginner bug in JavaScript. If user input comes from a form, it is always a string — even if they typed a number. "5" + 5 gives you "55", not 10.

A real example:

// User types their age into a form input
let userInput = "25"; // always comes as a string from inputs

let wrongResult = userInput + 5;
console.log(wrongResult); // "255" — wrong

let correctResult = Number(userInput) + 5;
console.log(correctResult); // 30 — correct

Number Coercion

Every other arithmetic operator — -, *, /, % — tries to convert values to numbers. Only + goes toward strings.

console.log("10" - 5);    // 5
console.log("10" * 2);    // 20
console.log("10" / 2);    // 5
console.log("abc" - 1);   // NaN — "abc" can't be converted to a number

Here's how JavaScript converts common values to numbers:

console.log(Number("42"));      // 42
console.log(Number("3.14"));    // 3.14
console.log(Number(""));        // 0   — empty string becomes 0
console.log(Number("  "));      // 0   — whitespace becomes 0
console.log(Number("abc"));     // NaN
console.log(Number(true));      // 1
console.log(Number(false));     // 0
console.log(Number(null));      // 0
console.log(Number(undefined)); // NaN

NaN — Not a Number — is what you get when a conversion is impossible. The value is still of type number, just invalid.

let result = Number("hello");
console.log(result);         // NaN
console.log(typeof result);  // "number"

// Check if something is NaN
console.log(isNaN(result));        // true
console.log(Number.isNaN(result)); // true — more reliable, use this one

Boolean Coercion — Truthy and Falsy

Every value in JavaScript is either truthy or falsy — meaning when used in a condition, it behaves like true or false.

There are only 6 falsy values in JavaScript. Memorize these:

Boolean(false);     // false
Boolean(0);         // false
Boolean(-0);        // false
Boolean("");        // false — empty string
Boolean(null);      // false
Boolean(undefined); // false
Boolean(NaN);       // false

Everything else is truthy — including things that might surprise you:

Boolean("0");        // true  — "0" is a non-empty string
Boolean("false");    // true  — still a non-empty string
Boolean([]);         // true  — empty array is truthy
Boolean({});         // true  — empty object is truthy
Boolean(-1);         // true  — any non-zero number is truthy

This matters most in if statements:

let username = "";

if (username) {
  console.log("Welcome, " + username);
} else {
  console.log("Please enter your name"); // this runs — "" is falsy
}
let cartItems = [];

if (cartItems.length) {
  console.log("You have items in your cart");
} else {
  console.log("Your cart is empty"); // this runs — 0 is falsy
}

Equality and Coercion — == vs ===

We touched on this in Operators. Now you understand why == is dangerous.

== does type coercion before comparing. === does not.

console.log(0 == false);    // true  — false coerced to 0
console.log(0 === false);   // false — number vs boolean

console.log("" == false);   // true  — both coerce to 0
console.log("" === false);  // false

console.log(null == undefined);  // true  — special rule in JS
console.log(null === undefined); // false

console.log(1 == "1");   // true  — "1" coerced to 1
console.log(1 === "1");  // false

== has a long rulebook of conversion logic that almost nobody remembers fully. === just checks if two values are identical — no magic.

Always use ===. You will never regret it.


Explicit Conversion — The Safe Way

When you need to convert types, do it yourself explicitly. Never rely on JavaScript to do it for you.

To Number

Number("42");      // 42
Number("3.14");    // 3.14
Number(true);      // 1
Number(false);     // 0
Number(null);      // 0
Number(undefined); // NaN
Number("abc");     // NaN

// Alternative for integers only
parseInt("42px");   // 42 — reads until it hits a non-number character
parseFloat("3.14rem"); // 3.14

parseInt and parseFloat are useful when values come with units attached — like CSS values.

To String

String(42);        // "42"
String(true);      // "true"
String(null);      // "null"
String(undefined); // "undefined"

// Or use .toString()
(42).toString();   // "42"
(255).toString(16); // "ff" — converts to hexadecimal

To Boolean

Boolean(1);    // true
Boolean(0);    // false
Boolean("");   // false
Boolean("hi"); // true

// The double-NOT trick — you'll see this in real code
console.log(!!1);   // true
console.log(!!0);   // false
console.log(!!"");  // false
console.log(!!"hi"); // true

!! converts any value to its boolean equivalent. The first ! flips it, the second ! flips it back — leaving you with the pure boolean.


Summary

  • Type coercion is JavaScript automatically converting one type to another
  • Implicit coercion — JavaScript does it silently, can cause bugs
  • Explicit coercion — you do it on purpose with Number(), String(), Boolean()
  • The + operator prefers strings — everything else prefers numbers
  • There are only 6 falsy values — everything else is truthy
  • Always use === to avoid coercion in comparisons
  • Form inputs always come as strings — always convert before doing math

On this page