Basic Types in TypeScript
Introduction
TypeScript’s type system starts with a small set of primitive and structural types you use everywhere: numbers, strings, booleans, arrays, tuples, enums, and a few special types for “anything,” “nothing,” and “no return.” This chapter shows how to annotate values, when each type fits, and pitfalls to avoid (especially any).
Prerequisites
- Your First TypeScript Program
- A project with
strict: trueintsconfig.json(recommended) - Familiarity with JavaScript values (strings, arrays,
null)
Primitive Types: number, string, boolean
| Type | Examples | Notes |
|---|---|---|
number | 42, 3.14, NaN | All JS numbers are IEEE doubles; no separate int |
string | "hi", 'a', `tpl` | Same string type for all quote styles |
boolean | true, false | Not truthy/falsy types—only the two literals |
const count: number = 10;
const label: string = "items";
const active: boolean = true;
const total: number = count * 2;
const summary: string = `${label}: ${total}`;Code explanation:
- Annotations after
:describe what may be stored in the variable - Operations that mix incompatible types (for example
count + label) are rejected at compile time
Arrays
Two equivalent forms:
// Element type followed by []
const scores: number[] = [90, 85, 88];
// Generic Array<Element>
const tags: Array<string> = ["ts", "types"];Code explanation:
number[]andArray<number>mean the same thing; pick one style per project- Empty arrays often need a hint:
const ids: number[] = []
Multidimensional arrays:
const matrix: number[][] = [
[1, 2],
[3, 4],
];Tuples: Fixed-Length, Typed Positions
A tuple is an array with a known length and type per index:
const pair: [string, number] = ["age", 30];
const name = pair[0];
const value = pair[1];Code explanation:
- Index
0isstring, index1isnumber - Assigning
pair[1] = "thirty"fails type-checking
Optional tuple elements (TypeScript 4+):
const row: [string, number?] = ["id"];Use tuples for small, ordered records (RGB, key-value pairs). For named fields, prefer objects and interfaces (later chapters).
Enums
Enums give names to related constants.
Numeric enum
enum Direction {
Up,
Down,
Left,
Right,
}
const move: Direction = Direction.Up;Code explanation:
- Members default to
0, 1, 2, ...unless you set values Direction.Upis a number at runtime
String enum
enum LogLevel {
Info = "INFO",
Warn = "WARN",
Error = "ERROR",
}
function log(level: LogLevel, text: string): void {
console.log(`[${level}] ${text}`);
}
log(LogLevel.Info, "Server started");Tip
Prefer const Objects in Modern Code
Many teams use as const objects instead of enum to avoid extra runtime code. Enums remain common in tutorials and legacy codebases—you should recognize them.
Special Types Overview
| Type | Meaning | Typical use |
|---|---|---|
any | Opt out of checking | Legacy migration (avoid in new code) |
unknown | Safe top type—must narrow before use | User input, JSON parse |
void | No useful return value | Functions that only side-effect |
null | Absence of value | Explicit null |
undefined | Uninitialized / missing | Optional parameters, missing props |
never | No possible value | Exhaustive checks, functions that always throw |
void
For functions that do not return a meaningful value:
function logMessage(text: string): void {
console.log(text);
}void is not the same as undefined in all strictness settings, but callers usually ignore the return. You will refine return types in the functions chapter.
null and undefined
With strictNullChecks (part of strict: true), null and undefined are not assignable to other types unless you allow them:
let title: string = "Draft";
// title = null; // Error under strictNullChecks
let subtitle: string | null = null;
subtitle = "Optional line";Code explanation:
string | nullis a union: either a string ornull- Unions are covered in depth later; here they model optional values explicitly
any: Escape Hatch (Use Sparingly)
let data: any = fetchSomething();
data.foo.bar(); // No compile-time error—unsafeany disables checking for that value. It propagates easily and hides bugs.
Warning
Avoid any in New Code
Prefer unknown or proper interfaces. Use any only for incremental migration with a plan to remove it.
unknown: Type-Safe “I Don’t Know Yet”
function parseJson(input: string): unknown {
return JSON.parse(input);
}
const value = parseJson('{"count": 3}');
// value.count; // Error: 'value' is of type 'unknown'
if (typeof value === "object" && value !== null && "count" in value) {
const obj = value as { count: number };
console.log(obj.count);
}Code explanation:
- You cannot use
unknownuntil you narrow or assert to a concrete type - Safer default than
anyfor external data
never
Functions that never return normally:
function fail(message: string): never {
throw new Error(message);
}
function infiniteLoop(): never {
while (true) {
// ...
}
}never also appears when TypeScript proves a variable cannot exist (exhaustive switch checks—later).
Literal Types (Preview)
Types can be exact values, not only broad primitives:
const mode: "light" | "dark" = "light";
const port: 3000 | 8080 = 3000;These are literal types combined with unions—very common for APIs and configuration.
Putting It Together
Code explanation:
- Object shape uses a
typealias (interfaces work similarly—next chapters) tagsis a string array;metais a two-string tupleStatusstring enum keeps allowed status values readable
Quick Reference
FAQ
Is number only integers?
No. TypeScript’s number matches JavaScript: integers and floats share one type. Use libraries or branded types if you need integers only.
Should I use Array<T> or T[]?
Either is fine. Stay consistent within a project; many style guides prefer T[] for simple arrays.
When should I use a tuple instead of an object?
Tuples suit fixed order and small arity (coordinates, [key, value]). Objects scale better when fields have names.
What is the difference between any and unknown?
any lets you do anything without checks. unknown forces you to validate or narrow before use—prefer unknown for untrusted data.
Are enums bad?
They are not “bad,” but they generate JavaScript objects. as const + union types is a modern alternative with zero enum runtime.
Does TypeScript have a char or byte type?
No built-in char/byte. Use number or Uint8Array when you need binary data.