Skip to main content
Why does "5" + 3 give you "53" but "5" - 3 gives you 2? Why does [] == ![] return true? How does JavaScript decide what type a value should be?
This surprising behavior is type coercion. JavaScript automatically converts values from one type to another. Understanding these rules helps you avoid bugs and write more predictable code.
What you’ll learn in this guide:
  • The difference between implicit and explicit coercion
  • How JavaScript converts to strings, numbers, and booleans
  • The 8 falsy values every developer must memorize
  • How objects convert to primitives
  • The famous JavaScript “WAT” moments explained
  • Best practices for avoiding coercion bugs
Prerequisites: This guide assumes you understand Primitive Types. If terms like string, number, boolean, null, and undefined are new to you, read that guide first!

What Is Type Coercion?

Type coercion is the automatic or implicit conversion of values from one data type to another in JavaScript. According to the ECMAScript specification, JavaScript performs these conversions through a set of “abstract operations” — internal algorithms like ToString, ToNumber, and ToBoolean. When you use operators or functions that expect a certain type, JavaScript will convert (coerce) values to make the operation work, sometimes helpfully, sometimes surprisingly. Understanding these conversion rules helps you write predictable, bug-free code.

The Shapeshifter Analogy

Imagine JavaScript as an overly helpful translator. When you give it values of different types, it tries to “help” by converting them, sometimes correctly, sometimes… creatively.
This “helpful” behavior is called type coercion. JavaScript automatically converts values from one type to another. Sometimes it’s useful, sometimes it creates bugs that will haunt your dreams.

Explicit vs Implicit Coercion

There are two ways coercion happens:
You control the conversion using built-in functions. This is predictable and intentional.
These functions — Number(), String(), Boolean(), parseInt(), and parseFloat() — give you full control.This is the safe way. You know exactly what’s happening.

Why Does JavaScript Do This?

JavaScript is a dynamically typed language. Variables don’t have fixed types. This flexibility means JavaScript needs to figure out what to do when types don’t match.
Other languages would throw an error. JavaScript tries to make it work. Whether that’s a feature or a bug… depends on who you ask!

The Three Types of Conversion

Here’s the most important rule: JavaScript can only convert to THREE primitive types: That’s it. No matter how complex the coercion seems, the end result is always a string, number, or boolean.

String Conversion

String conversion is the most straightforward. Almost anything can become a string.

When Does It Happen?

The toString() method and template literals are also common ways to convert values to strings.

String Conversion Rules

The + Operator’s Split Personality

The + operator is special: it does both addition and concatenation:
Common gotcha: The + operator with strings catches many developers off guard. If you’re doing math and get unexpected string concatenation, check if any value might be a string!

Number Conversion

Number conversion has more triggers than string conversion, and more edge cases to memorize.

When Does It Happen?

Number Conversion Rules

null vs undefined: Notice that Number(null) is 0 but Number(undefined) is NaN. This inconsistency trips up many developers!

Math Operators Always Convert to Numbers

Unlike +, the other math operators (-, *, /, %) only do math. They always convert to numbers:

The Unary + Trick

The unary + (plus sign before a value) is a quick way to convert to a number:

Boolean Conversion

Boolean conversion is actually the simplest. Every value is either truthy or falsy.

When Does It Happen?

The 8 Falsy Values (Memorize These!)

As documented in MDN’s reference on falsy values, there are 8 common values that convert to false. Everything else is true.
Technical note: There’s actually a 9th falsy value: document.all. It’s a legacy browser API that returns false in boolean context despite being an object. You’ll rarely encounter it in modern code, but it exists for backwards compatibility with ancient websites.

Everything Else Is Truthy!

This includes some surprises:
Common gotchas:

Logical Operators Don’t Return Booleans!

A common misconception: && and || don’t necessarily return true or false. They return one of the original values:

Object to Primitive Conversion

When JavaScript needs to convert an object to a primitive (including arrays), it follows a specific algorithm.

The ToPrimitive Algorithm

1

Check if already primitive

If the value is already a primitive (string, number, boolean, etc.), return it as-is.
2

Determine the 'hint'

JavaScript decides whether it wants a “string” or “number” based on context:
  • String hint: String(), template literals, property keys
  • Number hint: Number(), math operators, comparisons
  • Default hint: + operator, == (usually treated as number)
3

Try valueOf() or toString()

  • For number hint: try valueOf() first, then toString()
  • For string hint: try toString() first, then valueOf()
4

Return primitive or throw

If a primitive is returned, use it. Otherwise, throw TypeError.

How Built-in Objects Convert

Custom Conversion with valueOf and toString

You can control how your objects convert:

ES6 Symbol.toPrimitive

ES6 introduced a cleaner way to control conversion — Symbol.toPrimitive:

The == Algorithm Explained

The loose equality operator == is where type coercion gets wild. For a deeper dive into all equality operators, see our Equality Operators guide. Here’s how == actually works:

Simplified == Rules

1

Same type?

Compare directly (like ===).
2

null or undefined?

null == undefined is true. Neither equals anything else.
3

Number vs String?

Convert the string to a number.
4

Boolean involved?

Convert the boolean to a number FIRST.
5

Object vs Primitive?

Convert the object to a primitive.

Step-by-Step Examples

Just use ===! The triple equals operator never coerces types. If the types are different, it returns false immediately. This is almost always what you want.

Operators & Coercion Cheat Sheet

Quick reference for which operators trigger which coercion:

JavaScript WAT Moments

Let’s explore the famous “weird parts” that make JavaScript… special.
Use Number.isNaN() instead of the global isNaN() for reliable NaN checking.

Best Practices

How to avoid coercion bugs:
  1. Use === instead of == — No surprises, no coercion
  2. Be explicit — Use Number(), String(), Boolean() when converting
  3. Validate input — Don’t assume types, especially from user input
  4. Use Number.isNaN() — Not isNaN() or === NaN
  5. Be careful with + — Remember it concatenates if any operand is a string

When Implicit Coercion IS Useful

Stack Overflow’s 2023 Developer Survey reports that type-related bugs remain among the most common debugging challenges for JavaScript developers. Despite the gotchas, some implicit coercion patterns are actually helpful:

Anti-Patterns to Avoid


Key Takeaways

The key things to remember about Type Coercion:
  1. Three conversions only — JavaScript converts to String, Number, or Boolean — nothing else
  2. Implicit vs Explicit — Know when JS converts automatically vs when you control it
  3. The 8 common falsy values — false, 0, -0, 0n, "", null, undefined, NaN — everything else is truthy (plus the rare document.all)
  4. + is special — It prefers string concatenation if ANY operand is a string
  5. - * / % are consistent — They ALWAYS convert to numbers
  6. == coerces, === doesn’t — Use === by default to avoid surprises
  7. null == undefined — This is true, but neither equals anything else with ==
  8. Objects convert via valueOf() and toString() — Learn these methods to control conversion
  9. When in doubt, be explicit — Use Number(), String(), Boolean()
  10. NaN is unique — It’s the only value not equal to itself; use Number.isNaN() to check

Test Your Knowledge

Answer: "53" (string)The + operator, when one operand is a string, performs string concatenation. The number 3 is converted to "3", resulting in "5" + "3" = "53".
Answer:
  1. false
  2. 0
  3. -0
  4. 0n (BigInt zero)
  5. "" (empty string)
  6. null
  7. undefined
  8. NaN
Everything else is truthy, including [], {}, "0", and "false".Bonus: There’s also a 9th falsy value — document.all — a legacy browser API you’ll rarely encounter.
Answer: This is a multi-step coercion:
  1. ![] evaluates first: arrays are truthy, so ![] = false
  2. Now we have [] == false
  3. Boolean converts to number: [] == 0
  4. Array converts to primitive: "" == 0
  5. String converts to number: 0 == 0
  6. Result: true
Answer:
  • === (strict equality) never coerces. If types differ, it returns false immediately.
  • == (loose equality) coerces values to the same type before comparing, following a complex algorithm.
Best practice: Use === unless you specifically need coercion.
Answer:
This inconsistency is a common source of bugs. null converts to 0 (like “nothing” = zero), while undefined converts to NaN (like “no value” = not a number).
Answer: "1hello"Step by step:
  1. true + false = 1 + 0 = 1 (booleans → numbers)
  2. 1 + "hello" = "1hello" (number → string for concatenation)

Frequently Asked Questions

Type coercion is JavaScript’s automatic conversion of values from one type to another. According to the ECMAScript specification, all coercion ultimately converts to one of three primitive types: String, Number, or Boolean. It can be implicit (triggered by operators) or explicit (using functions like Number(), String(), or Boolean()).
There are 8 common falsy values: false, 0, -0, 0n (BigInt zero), "" (empty string), null, undefined, and NaN. As documented by MDN, every other value in JavaScript is truthy — including empty arrays [], empty objects {}, and the string "0".
The + operator has a dual role: it performs both addition and string concatenation. When either operand is a string, + concatenates. The - operator only performs subtraction, so it always converts operands to numbers. This asymmetry is one of the most frequently asked JavaScript interview questions according to Stack Overflow surveys.
Explicit coercion is when you intentionally convert types using functions like Number("42") or String(42). Implicit coercion happens automatically when JavaScript encounters mismatched types in operations — for example, "5" - 3 implicitly converts "5" to the number 5. Most style guides recommend explicit coercion for clarity.
JavaScript uses the ToPrimitive abstract operation, which checks for a Symbol.toPrimitive method first, then falls back to valueOf() and toString(). For number hints, valueOf() is tried first; for string hints, toString() is tried first. Arrays convert via toString(), which is why [1,2,3] + "" produces "1,2,3".

Primitive Types

Understanding the basic data types that coercion converts between

Primitives vs Objects

How primitives and objects behave differently during coercion

Equality Operators

Deep dive into ==, ===, and how coercion affects comparisons

JavaScript Engines

How engines like V8 implement type coercion internally

Reference

Type Coercion — MDN

Official MDN glossary entry explaining type coercion fundamentals.

Equality Comparisons — MDN

Comprehensive guide to ==, ===, Object.is() and the coercion rules behind each.

Type Conversion — MDN

The difference between type coercion (implicit) and type conversion (explicit).

Truthy and Falsy — MDN

Complete list of falsy values and how boolean context works.

Articles

JavaScript Type Coercion Explained

Comprehensive freeCodeCamp article by Alexey Samoshkin covering all coercion rules with tons of examples and quiz questions. One of the best resources available.

What you need to know about Javascript's Implicit Coercion

Practical guide by Promise Tochi covering implicit coercion patterns, valueOf/toString, and common gotchas with clear examples.

Object to Primitive Conversion

Deep-dive from javascript.info into how objects convert to primitives using Symbol.toPrimitive, toString, and valueOf. Essential for advanced understanding.

You Don't Know JS: Types & Grammar, Ch. 4

Kyle Simpson’s definitive deep-dive into JavaScript coercion. Explains abstract operations, ToString, ToNumber, ToBoolean, and the “why” behind every rule. Free to read online.

Videos

== ? === ??? ...#@^% — JSConf EU

Entertaining JSConf talk by Shirmung Bielefeld exploring the chaos of JavaScript equality operators with live examples and audience participation.

Coercion in Javascript — Hitesh Choudhary

Hitesh walks through coercion step-by-step in the browser console, showing exactly what JavaScript does at each conversion. Good pace for beginners.

What is Coercion? — Steven Hancock

Steven breaks down the three conversion types (string, number, boolean) with simple examples. Short video that covers the fundamentals quickly.
Last modified on February 17, 2026