What are Types?
Types describe the shape of data in your program. TypeScript adds a type system on top of JavaScript that catches bugs at compile time instead of at runtime.
// JavaScript: this bug only shows up at runtime
function double(x) {
return x * 2;
}
double("hello"); // NaN — no error until you run it
// TypeScript: caught immediately
function double(x: number): number {
return x * 2;
}
double("hello"); // Error: Argument of type 'string' is not assignable to parameter of type 'number'
Primitive Types
TypeScript has the same primitive types as JavaScript, plus a few extras:
// String
let name: string = "Sabaoon";
// Number (integers and floats are both 'number')
let age: number = 25;
let price: number = 9.99;
// Boolean
let isActive: boolean = true;
// Null and Undefined
let nothing: null = null;
let notDefined: undefined = undefined;
// BigInt
let huge: bigint = 100n;
// Symbol
let id: symbol = Symbol("id");Type Annotations vs. Type Inference
You don't always need to write types explicitly. TypeScript can infer them from the value you assign:
// Explicit annotation — you write the type
let city: string = "Peshawar";
// Type inference — TypeScript figures it out
let country = "Pakistan"; // inferred as string
let count = 42; // inferred as number
let done = false; // inferred as boolean
Rule of thumb: let TypeScript infer when the type is obvious from the value. Add annotations when the type isn't clear, or when you want to be explicit about a function's contract.
Arrays
There are two syntaxes for typed arrays:
// Bracket syntax (preferred)
let scores: number[] = [95, 87, 92];
let names: string[] = ["Alice", "Bob"];
// Generic syntax
let ids: Array<number> = [1, 2, 3];
// TypeScript infers element types from the values
let colors = ["red", "green", "blue"]; // string[]
// Mixed arrays use union types
let mixed: (string | number)[] = ["hello", 42, "world"];
Objects
You can type objects inline or with named types:
// Inline object type
let user: { name: string; age: number; email: string } = {
name: "Sabaoon",
age: 25,
email: "sabaoon@example.com",
};
// Optional properties use ?
let config: { debug?: boolean; verbose?: boolean } = {};
config.debug = true; // fine
config.verbose = undefined; // also fine
// Readonly properties
let point: { readonly x: number; readonly y: number } = { x: 10, y: 20 };
// point.x = 5; // Error: Cannot assign to 'x' because it is a read-only property
Tuples
Tuples are fixed-length arrays where each position has a specific type:
// A tuple of [string, number]
let pair: [string, number] = ["age", 25];
// Destructuring works as expected
let [label, value] = pair; // label: string, value: number
// Named tuples (TypeScript 4.0+) — labels are for documentation only
type Coordinate = [x: number, y: number];
let point: Coordinate = [10, 20];Enums
Enums define a set of named constants:
// Numeric enum (values auto-increment from 0)
enum Direction {
Up, // 0
Down, // 1
Left, // 2
Right, // 3
}
let move: Direction = Direction.Up;
// String enum (each value must be explicitly set)
enum Status {
Active = "ACTIVE",
Inactive = "INACTIVE",
Pending = "PENDING",
}
let userStatus: Status = Status.Active;Tip: Many TypeScript developers prefer union types (
type Direction = "up" | "down" | "left" | "right") over enums because they produce less JavaScript output and are simpler to use.
The any, unknown, and never Types
// any — disables type checking (avoid when possible)
let anything: any = "hello";
anything = 42;
anything.foo.bar; // no error, but could crash at runtime
// unknown — safe alternative to any (must narrow before use)
let input: unknown = "hello";
// input.toUpperCase(); // Error: Object is of type 'unknown'
if (typeof input === "string") {
input.toUpperCase(); // OK after narrowing
}
// never — represents values that never occur
function throwError(message: string): never {
throw new Error(message);
}Type Assertions
Sometimes you know more about a type than TypeScript does:
// The 'as' syntax (preferred)
let input = document.getElementById("name") as HTMLInputElement;
input.value = "hello";
// Angle bracket syntax (not usable in TSX files)
let input2 = <HTMLInputElement>document.getElementById("name");
Use assertions sparingly — they bypass the type checker, so an incorrect assertion can cause runtime bugs.