TypeScript Fundamentals
Types, interfaces, generics, enums, and utility types
Core Type System
ts
// Type Basics
// Primitive types
let name: string = "Alice";
let age: number = 28;
let active: boolean = true;
// Arrays & Tuples
let ids: number[] = [1, 2, 3];
let pair: [string, number] = ["age", 28];
// Union & Intersection
type Status = "active" | "inactive" | "banned";
type AdminUser = User & { permissions: string[] };
// Literal types
type Direction = "up" | "down" | "left" | "right";
// Interface — extendable, for objects
interface User {
id: number;
name: string;
email: string;
role?: string; // optional
readonly createdAt: Date;
}
// Type alias — for unions, primitives, tuples
type Result<T> = { success: true; data: T } | { success: false; error: string };
// Extending interfaces
interface Admin extends User {
permissions: string[];
}Generics & Utility Types
ts
// Advanced TypeScript
// Generics — reusable type-safe functions
function identity<T>(value: T): T {
return value;
}
identity<string>("hello"); // type-safe
// Generic constraints
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
// Utility types
type PartialUser = Partial<User>; // all optional
type RequiredUser = Required<User>; // all required
type ReadonlyUser = Readonly<User>; // all readonly
type UserPreview = Pick<User, "id" | "name">;
type UserUpdate = Omit<User, "id" | "createdAt">;
type UserRecord = Record<string, User>; // { [key: string]: User }
// Enums
enum HttpStatus {
OK = 200,
NotFound = 404,
ServerError = 500,
}
// Type narrowing
function processValue(value: string | number) {
if (typeof value === "string") {
return value.toUpperCase(); // TS knows it's string
}
return value.toFixed(2); // TS knows it's number
}
// Discriminated unions
type Shape =
| { kind: "circle"; radius: number }
| { kind: "rect"; width: number; height: number };
function area(shape: Shape): number {
switch (shape.kind) {
case "circle": return Math.PI * shape.radius ** 2;
case "rect": return shape.width * shape.height;
}
}Interview Q&A
💬 Interface vs Type — when to use which?
Interfaces are best for object shapes and can be extended/merged. Types are more flexible — unions, intersections, primitives, tuples. Use interfaces for public APIs (extendable), types for everything else.
💬 What is type narrowing?
Type narrowing is when TypeScript reduces a union type to a more specific type based on control flow checks (typeof, instanceof, in operator, discriminated unions). It lets TS infer the correct type in each branch.