Declaring an Interface
You have been writing object shapes with type Task = {...}. Open almost any TypeScript codebase or library, though, and you will see the other way of naming a shape everywhere: interface. This section makes it yours, starting with how to declare one.
The rule
An interface is a named object shape: properties, modifiers and methods.
interface Task {
readonly id: number;
title: string;
done: boolean;
notes?: string;
complete(): void;
}Line by line:
title: string— a required property. EveryTaskmust have it.notes?: string— optional. It may be missing, so reading it gives astringorundefined.readonly id: number— can be set when the object is created but not reassigned afterwards. This is a compile-time rule only.complete(): void— a method signature: everyTaskhas acompletemethod that takes no arguments and returns nothing useful.
Members can be separated by semicolons, commas, or just line breaks. Interfaces are erased at compile time; they only describe shapes.
Two more members you will meet often:
interface TaskIndex {
[id: string]: Task; // index signature: any string key maps to a Task
}
interface Formatter {
(task: Task): string; // call signature: the value itself is a function
}An index signature describes objects used as dictionaries, where you do not know the key names in advance. A call signature describes something you can call like a function.
A class can promise to follow an interface with implements. The compiler then checks that the class really has every member:
class SimpleTask implements Task {
readonly id: number;
title: string;
done = false;
constructor(id: number, title: string) {
this.id = id;
this.title = title;
}
complete(): void { this.done = true; }
}The shortcut
Read each member left to right as three questions: "Can it change?" (readonly), "Is it always there?" (?), "What is it?" (the type, or a method signature with ()).
readonly id: numberCannot change after creation, always there, a number.
Drills
Answer fast — trust the rule.
What does notes?: string in an interface mean?
interface Task { readonly id: number }. What happens on task.id = 5;?
Which member says every object has a start method that takes a number and returns nothing?
What does [id: string]: Task; inside an interface describe?
Remember
- An interface is a named object shape: properties, modifiers and methods.
- Read each member as: can it change, is it always there, what is it?
- Trap:
readonlyis a compile-time check only; nothing is frozen at runtime.
