Introduction
JavaScript’s type coercion is a source of both power and confusion. This post explores how JavaScript converts values between types, the rules behind these conversions, common pitfalls, and how modern tools like TypeScript help you avoid mistakes. Examples and references are provided for deeper understanding.
Operator Behaviors
Addition and Arithmetic
The + operator performs string concatenation if either operand is a string (for example, "5" + 3 and 5 + "3" both yield "53"). Otherwise, it does numeric addition. Operators like -, *, /, and % always convert operands to numbers: "10" - 4 is 6, true * 2 is 2 (since true becomes 1), null / 2 is 0, and undefined % 2 is NaN.BigInt Mixing Context
Mixing BigInt and Number only throws a TypeError in arithmetic operations (like 1n + 2). You can still compare them with == or === (though === will always be false). To safely perform arithmetic, explicitly convert types: use BigInt(number) or Number(bigint) as needed. For example: BigInt(2) + 1n is 3n, Number(1n) + 2 is 3.// Addition and arithmetic
"5" + 3; // "53"
5 + "3"; // "53"
"10" - 4; // 6
true * 2; // 2
null / 2; // 0
undefined % 2; // NaN
// BigInt mixing
1n + 2; // TypeError
1n === 1; // false
1n == 1; // true
BigInt(2) + 1n; // 3n
Number(1n) + 2; // 3
Other Quirks and Surprises
JavaScript’s flexibility can lead to results that seem nonsensical at first glance. Grouping and understanding these quirks helps you avoid bugs.[] + [] // '' (empty string)
[] + {} // '[object Object]'
{} + [] // 0
typeof NaN // 'number'
TypeScript: Safer JavaScript
TypeScript’s static typing catches mismatched types at compile time, preventing unintended coercion and runtime surprises. Use it to ensure your variables, functions, and objects are used as intended—especially in large codebases or when working with teams.// TypeScript example
function add(a: number, b: number): number {
return a + b;
}
add(1, 2); // OK
add(1, "oops"); // Error: Argument of type 'string' is not assignable to parameter of type 'number'
add(1n, 2); // Error: Cannot mix BigInt and other types
Conclusion
Mastering JavaScript’s type coercion means understanding both its power and its pitfalls. By learning how values are converted and where surprises can arise, you’ll write code that’s more robust, predictable, and easier to debug. When in doubt, use explicit conversions and strict equality, and consider TypeScript for even greater safety. With these habits, you can take full advantage of JavaScript’s flexibility—without falling into its traps.