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 errorBoth 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 0Explicit 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 → falseExplicit 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" — sameOrder 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 — correctNumber 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 numberHere'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)); // NaNNaN — 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 oneBoolean 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); // falseEverything 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 truthyThis 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.14parseInt 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 hexadecimalTo 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