Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The !== (strict inequality) operator evaluates whether two operands are not identical. It returns true if the operands differ in either data type or value, and false if they share the exact same type and value, with the notable exception of NaN. Unlike the loose inequality operator (!=), !== never performs implicit type coercion during evaluation.
operand1 !== operand2

Evaluation Mechanics

At runtime, the operator follows strict equality resolution rules:
  1. Type Comparison: If the runtime types of operand1 and operand2 differ, it immediately evaluates to true.
  2. Value Comparison: If the types are identical, it compares the underlying values. If the values differ, it evaluates to true.
  3. The NaN Exception: In JavaScript and TypeScript, NaN (Not-a-Number) is of type number but is strictly unequal to itself. Therefore, NaN !== NaN evaluates to true. To accurately check if a value is NaN, you must use Number.isNaN() rather than the !== operator.
  4. Reference Types: For objects, arrays, and functions, !== evaluates memory identity (reference equality) rather than structural equivalence. Two distinct objects with identical properties will evaluate to true because they occupy different memory addresses.

TypeScript Compiler Behavior

While the runtime behavior is identical to JavaScript, TypeScript applies static type analysis to the !== operator at compile time. If the TypeScript compiler determines that the types of the two operands have no intersection (i.e., they are mutually exclusive or non-overlapping), it will throw a ts(2367) compiler error. TypeScript flags this because comparing two completely unrelated types with !== will always evaluate to true, indicating a logical flaw in the code.
let str: string = "10";
let num: number = 10;

// Compiler Error ts(2367): This condition will always return 'true' 
// since the types 'string' and 'number' have no overlap.
const isDifferent = str !== num; 
If types already overlap (such as a union type intersecting with a primitive), the compiler naturally allows the check. However, to perform a strict inequality check across unrelated or non-overlapping types, you must bypass the compiler by casting one or both operands to a top type like any or unknown.
let str: string = "10";
let num: number = 10;

// Bypassing the compiler check for non-overlapping types using 'unknown'
const isForcedDifferent = (str as unknown) !== num; 

let val1: string | number = "10";
let val2: number = 10;

// Valid compilation: 'val1' could potentially be a number, 
// so the types naturally overlap. Evaluates to true at runtime.
const isDifferent = val1 !== val2; 

Reference Evaluation Example

When evaluating reference types, the compiler allows the comparison as long as the types overlap, but the runtime evaluation strictly checks the memory pointer.
const objA: { id: number } = { id: 1 };
const objB: { id: number } = { id: 1 };
const objC = objA;

const check1 = objA !== objB; // Valid compilation. Evaluates to true (different references).
const check2 = objA !== objC; // Valid compilation. Evaluates to false (same reference).
Master TypeScript with Deep Grasping Methodology!Learn More