TypeScript Types and Interfaces
Defining types and interfaces in TypeScript
What you'll learn
Master TypeScript's primitive and object types
Use union, intersection, and literal types for precise typing
Define tuples and enum types for structured data
Understand type inference and when to add explicit annotations
Work with optional properties, readonly, and index signatures
Use type assertions and the non-null assertion operator correctly
TypeScript offers two primary ways to define object shapes.
Interface
interface User {
id: string
name: string
email: string
readonly createdAt: Date // Can't be modified after creation
}
interface Admin extends User {
role: "admin"
permissions: string[]
}
const user: User = {
id: "1",
name: "Alice",
email: "alice@example.com",
createdAt: new Date(),
}
Type Alias
type Status = "active" | "inactive" | "pending"
type Point = {
x: number
y: number
}
// Union types
type Result<T> = { success: true; data: T } | { success: false; error: string }
Interface vs Type
| Aspect | Interface | Type |
|---|---|---|
| Extending | extends | & intersection |
| Declaration merging | Yes | No |
| Union types | No | Yes |
| Performance | Better | Good |
Utility Types
type Partial<T> = { [P in keyof T]?: T[P] } // All optional
type Required<T> = { [P in keyof T]-?: T[P] } // All required
type Pick<T, K extends keyof T> = { [P in K]: T[P] } // Subset
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>> // Exclude
Next Steps
Key Takeaways
TypeScript infers types from values — explicit annotations are needed when inference is insufficient
Union types (A | B) allow a value to be one of several types; intersection types (A & B) require all properties
Literal types restrict a variable to specific string/number values, enabling enum-like patterns
Tuple types ([string, number]) define fixed-length arrays with typed positions
readonly prevents property reassignment and readonly arrays prevent mutation methods like push