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 ~ (Bitwise NOT) operator is a unary operator that performs bitwise inversion on its operand. For standard numbers, it coerces the evaluated operand into a 32-bit signed integer and yields the two’s complement inverse by flipping every 0 to 1 and every 1 to 0. For bigint operands, it performs arbitrary-precision bitwise inversion without 32-bit truncation, returning a bigint.
~expression

Execution Mechanics

When the TypeScript compiler and underlying JavaScript engine process the ~ operator, the execution path diverges based on the evaluated type of the operand: For number and non-bigint types:
  1. Evaluation and Coercion: The expression is evaluated. Non-numeric values undergo standard ECMAScript type coercion to a number (e.g., null becomes 0, undefined becomes NaN).
  2. ToInt32 Conversion: The numeric value is cast to a 32-bit signed integer using two’s complement representation. Floating-point numbers are truncated to integers. Any NaN or Infinity values are converted to 0.
  3. Bitwise Inversion: Every bit in the 32-bit sequence is inverted.
  4. Return: The resulting 32-bit binary sequence is returned as a standard number.
For bigint types:
  1. Evaluation: The expression is evaluated as a bigint.
  2. Arbitrary-Precision Inversion: The operator computes the bitwise NOT of the arbitrary-precision integer. It conceptually treats the bigint as a two’s complement binary representation with an infinite number of leading sign bits, flipping all bits without applying any 32-bit truncation.
  3. Return: The inverted value is returned as a bigint.
Mathematically, for any given numeric or bigint value x, the operation ~x evaluates to -(x + 1).

Syntax and Behavior Visualization

// 1. Positive Integer Inversion (number)
const pos: number = 5;
// 32-bit binary of 5:  00000000000000000000000000000101
// Bitwise NOT (~5):    11111111111111111111111111111010
// Two's complement:    -6
console.log(~pos); // Output: -6

// 2. BigInt Inversion (Arbitrary Precision)
const bigPos: bigint = 5n;
// Evaluates to -(5n + 1n) without 32-bit truncation
console.log(~bigPos); // Output: -6n

const largeBigInt: bigint = 9007199254740991n;
console.log(~largeBigInt); // Output: -9007199254740992n

// 3. Negative Integer Inversion (number)
const neg: number = -5;
// 32-bit binary of -5: 11111111111111111111111111111011
// Bitwise NOT (~-5):   00000000000000000000000000000100
// Decimal:             4
console.log(~neg); // Output: 4

// 4. Floating-Point Truncation
const float: number = 5.99;
// Truncated to 5 via ToInt32 before bitwise inversion
console.log(~float); // Output: -6

// 5. Non-Numeric Coercion
const str: string = "42";
console.log(~(str as any)); // Output: -43 (String "42" coerces to 42)

// null coerces to 0. ~0 is -1.
console.log(~(null as any)); // Output: -1 

// undefined coerces to NaN. NaN coerces to 0 in bitwise operations. ~0 is -1.
console.log(~(undefined as any)); // Output: -1
Note: In the coercion examples, the as any type assertion is grouped within parentheses to bypass TypeScript’s static type checker before the unary operator is applied. TypeScript intentionally flags bitwise operations on non-numeric types as errors to enforce type safety, though the runtime mechanics remain identical to standard ECMAScript behavior.
Master TypeScript with Deep Grasping Methodology!Learn More