Skip to main content
The << (Left Shift) operator is a binary bitwise operator that shifts the binary representation of its left operand to the left by the number of bits specified by its right operand. In TypeScript, the operator’s mechanical behavior depends entirely on whether the operands are of type number or bigint.

Syntax

Execution Mechanics: number Operands

When both operands are of type number, the operator adheres to the following 32-bit integer semantics:
  1. Type Coercion: Both operands are implicitly converted to 32-bit signed integers (Int32) using two’s complement representation. Any fractional parts are truncated.
  2. Right Operand Masking (Modulo 32): The shift amount is strictly evaluated as expression2 & 0x1F (equivalent to expression2 % 32). Attempting to shift by 32 bits or more wraps around. For example, shifting by 33 is identical to shifting by 1.
  3. Bit Shifting & Zero-Fill: The bits of the left operand are moved to the left. Vacated bit positions on the right are filled with zeroes (0).
  4. Discard & Sign Inversion: Bits shifted beyond the 32nd bit boundary on the left are permanently discarded. Because the result is constrained to a 32-bit signed integer, shifting a 1 into the most significant bit (MSB, the 32nd bit) alters the sign of the resulting number, yielding a negative value.
  5. Return: The operation evaluates to a standard TypeScript number.

Execution Mechanics: bigint Operands

When both operands are of type bigint, the operator scales to arbitrary-precision integers:
  1. No 32-bit Truncation: The operation does not coerce values to 32-bit integers. The binary representation grows as needed to accommodate the shifted value.
  2. No Masking: The right operand is not subjected to a modulo 32 operation. 1n << 33n will literally shift the bit 33 positions to the left.
  3. No Discarding: Bits are never discarded beyond a boundary.
  4. Return: The operation evaluates to a bigint.
(Note: The right operand must evaluate to a non-negative bigint, otherwise a runtime RangeError is thrown).

TypeScript Static Type Checking

Unlike JavaScript’s runtime semantics—which implicitly coerce non-numeric types like undefined or null to 0—TypeScript’s static type checker strictly forbids this.
  • Valid Types: Operands must be of type number, bigint, any, or an enum.
  • Type Mixing: TypeScript forbids mixing number and bigint across the operator. Attempting 1n << 2 results in TS2365: Operator '<<' cannot be applied to types 'bigint' and 'number'.
  • Non-Numeric Operands: Attempting to use types like undefined, string, or boolean will throw a compilation error: TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.

Mathematical Equivalence

Mechanically, a << b yields the exact integer result of a×2ba \times 2^b. For number types, this equivalence only holds true provided the operation does not trigger a 32-bit overflow. For bigint types, this mathematical equivalence is absolute.

Code Visualization

Tired of Poor TypeScript Skills? Fix That With Deep Grasping!Learn More