3. Types, interfaces & inference
TypeScript · 44 pages source format
type and interface define object shapes. Use interface for object contracts, type for unions and computed shapes. Inference fills types when obvious. Annotate public API boundaries; let inference handle locals.
What you'll learn
- type vs interface
- Optional & readonly
- Type inference
- Function types
- Literal types
Object shapes
interface User { id: number; name: string; email?: string }. Optional with ?. readonly for immutability hints.
interface User {
id: number
name: string
email?: string
readonly createdAt: string
}Do this now
Define User, Product, and Order interfaces for a shop domain. Include optional fields.
type vs interface
Interface: extend with extends, merge declarations. Type: unions, intersections, mapped types. For object-only shapes, either works — pick one style per project.
Do this now
Write same shape as interface and type alias. Extend both with AdminUser adding role.
Function types
type Handler = (event: MouseEvent) => void. Or inline: function greet(name: string): string.
Do this now
Type your utils: titleCase(str: string): string, sum(...nums: number[]): number.
Inference in action
const x = [1, 2, 3] infers number[]. let the compiler infer locals; annotate function returns at module boundaries.
Do this now
Remove explicit types from one function body. Confirm hover shows correct inferred type.
Pro tip. If inference result is too wide (string instead of "admin"|"user"), add as const or explicit annotation.
Literal and template types
type Status = "pending" | "active" | "archived". Template: type EventName = `on${Capitalize<string>}`.
Do this now
Define OrderStatus union. Function setStatus(id: number, status: OrderStatus) with exhaustiveness.