Base CS from zero
Primitive types
You now know that a type is an interpretation rule for bits. The natural next question is: what are the actual types available in the language you are learning?
In JavaScript and TypeScript, every value belongs to one of a small set of built-in categories. The simplest category members — those that hold a single, indivisible piece of data — are called primitive types. They are the bottom of the type hierarchy: numbers, text characters, true/false decisions, “nothing here”, “not yet set”. You cannot break a primitive value into smaller typed parts.
This lesson walks through each primitive type in JS/TS, grounds each in its bit-level
representation, and introduces typeof — the runtime’s way of telling you which
interpretation rule it is applying to a value.
After this lesson you can name the five primitive type categories you meet in everyday JS/TS code, describe what
each represents at the bit level, predict the result of a typeof expression for any
primitive value, and explain what null and undefined mean as distinct absence values.
JavaScript and TypeScript define five primitive value categories you meet in everyday code:
-
number— any numeric value: integers, fractions, and the special IEEE 754 valuesInfinity,-Infinity, andNaN. Internally stored as a 64-bit IEEE 754 double-precision floating-point number (8 bytes). Even integers like42are stored this way — JS has no separate integer type. -
string— a sequence of Unicode code points. In the V8 engine, a short string may be stored as a sequence of 16-bit UTF-16 code units in contiguous memory. A string value is not a single byte; it is a structured value with a length and a block of character data. -
boolean— exactly two values:trueandfalse. At the hardware level this maps to a 1-bit concept (though engines typically store it as a tagged word, not a single bit, for alignment reasons). The semantics: one of two mutually exclusive states. -
null— the deliberate absence of any value. A programmer writesnullto say “this slot holds nothing, intentionally.” There is exactly one null value. -
undefined— the unintentional or unset absence of a value. A declared variable that has not yet been assigned holdsundefined. There is exactly one undefined value.
The TC39 spec actually defines seven primitive types: the five above plus symbol
(added in ES2015, for unique opaque identifiers) and bigint (added in ES2020, for
integers larger than Number.MAX_SAFE_INTEGER). This lesson covers the five you encounter
in everyday code; symbol and bigint serve specialised use cases you will meet later.
The typeof operator is how the runtime reports a value’s type. Given any expression,
typeof expr returns a string naming the type. For primitives:
| Value | typeof result |
|---|---|
42 | "number" |
"hello" | "string" |
true | "boolean" |
undefined | "undefined" |
null | "object" ← historical quirk |
The null case is a well-known language quirk: typeof null returns "object" due to
a bug in the original JS implementation that could not be fixed for backwards
compatibility. In practice: null is a primitive, not an object.
1
// 1. number — 64-bit IEEE 754 double in memory
2
const temperature = 36.6;
3
const count = 100;
4
const big = 9007199254740991; // Number.MAX_SAFE_INTEGER
5
6
console.log(typeof temperature); // "number"
7
console.log(typeof count); // "number"
8
console.log(typeof NaN); // "number" — NaN is a numeric bit pattern
9
10
// 2. string — sequence of Unicode code points
11
const greeting = "hello";
12
const empty = "";
13
14
console.log(typeof greeting); // "string"
15
console.log(greeting.length); // 5 — length is part of the structured value
16
17
// 3. boolean — true or false only
18
const isReady = true;
19
const isOver = false;
20
21
console.log(typeof isReady); // "boolean"
22
23
// 4. null — deliberate absence
24
const slot = null;
25
console.log(typeof slot); // "object" — historical quirk, null IS a primitive
26
console.log(slot === null); // true — test for null using ===, not typeof
27
28
// 5. undefined — unset / not-yet-assigned
29
let future; // declared but not assigned
30
console.log(typeof future); // "undefined"
31
console.log(future === undefined);// true
- L2 number: stores 36.6 as a 64-bit IEEE 754 double (8 bytes)
- L7 typeof returns the string name of the type
- L8 NaN is a special IEEE 754 bit pattern, still type 'number'
- L12 string: length property reports how many code points
- L17 boolean: exactly two values, true and false
- L21 null: typeof returns 'object' — known JS bug, not fixable for compat
- L22 Use === null to detect null, not typeof
- L26 undefined: variable declared but never assigned
Watch how typeof responds to each kind of value. We trace a small program that assigns
five variables (one for each of the five everyday primitive types) and logs their typeof result.
1
const n = 42;
2
const s = 'A';
3
const b = true;
4
const x = null;
5
let u;
6
console.log(typeof n, typeof s, typeof b, typeof x, typeof u);
Common mistake
null and undefined look similar but mean different things. null is a deliberate
programmer choice: “I am explicitly saying this slot holds nothing.” undefined is
automatic: “this variable was declared but never given a value, or this property does not
exist.” Treat them as two distinct absence states. In TypeScript strict mode, the compiler
tracks them separately — a function that might return null is different from one that
might return undefined.
How many bytes does a JS number (IEEE 754 double) occupy in memory?
What does typeof 42 return? (Enter the ASCII code of the first character of the result string 'number', which starts with 'n'. ASCII 'n' = 110.)
A variable is declared with let x; and never assigned. What is typeof x in terms of a number — typeof 'undefined' has how many characters?
How many distinct boolean values exist in JS? (true and false.)
What does typeof null return as a string length? The string is 'object' — how many characters does 'object' have?
Which of the following correctly describes what typeof null returns, and why?
JavaScript and TypeScript define five primitive types you meet in everyday code:
number (64-bit IEEE 754 double), string (Unicode sequence), boolean (true or false),
null (deliberate absence), and undefined (uninitialised or absent). (The full spec adds
symbol and bigint, bringing the total to seven — covered when you need them.) Each
primitive represents a specific interpretation rule applied to the bits the runtime stores.
The typeof operator returns the name of that rule as a string — with one historical
quirk: typeof null returns "object", not "null". Primitive values are indivisible:
you cannot read a sub-field out of 42 the way you can read a property out of an object.
They are the atomic building blocks from which all JS/TS values are made.