TypeScript Interfaces
Describe the shape of an object, including optional properties.
On this page
TypeScript type annotations and JavaScript objects.
- Describe the shape of an object, including optional properties.
- Predict the sample output and explain the state changes.
- Complete the practice task and check the boundary cases.
The concept
An interface names the shape an object must have: which properties exist and what type each one is. TypeScript checks this structurally, so any object with the right properties fits, with no need to declare that it implements the interface.
A property marked with ? is optional, so its type includes undefined. The nullish coalescing operator ?? supplies a fallback only when the value is null or undefined, which makes it safer than || for values such as 0 or an empty string.
Code example
interface Student {
name: string;
score: number;
email?: string;
}
function describe(student: Student): string {
const contact = student.email ?? "no email";
return `${student.name}: ${student.score} (${contact})`;
}
const ada: Student = { name: "Ada", score: 91 };
const grace: Student = { name: "Grace", score: 88, email: "grace@example.com" };
console.log(describe(ada));
console.log(describe(grace));Ada: 91 (no email) Grace: 88 (grace@example.com)
Follow the code
Open the walkthrough to inspect the example one step at a time.
Show guided walkthrough
interface Student { name: string; score: number; email?: string;} function describe(student: Student): string { const contact = student.email ?? "no email"; return `${student.name}: ${student.score} (${contact})`;} const ada: Student = { name: "Ada", score: 91 };const grace: Student = { name: "Grace", score: 88, email: "grace@example.com" };console.log(describe(ada));console.log(describe(grace));Follow the example
Start to inspect the source, values, and output. These prepared steps explain the published sample; grouped loop steps describe multiple iterations.
View the complete dry-run table
| Step / line | What happens | State after step | Output so far |
|---|---|---|---|
| Declare the shape: name and score are required, email may be missing. | — | — | |
| Use the email if present, otherwise the fallback text. | — | — | |
| ada has no email, so the fallback is used. | contact = "no email" | Ada: 91 (no email) | |
| grace supplies an email, so it is used. | contact = "grace@example.com" | Ada: 91 (no email) Grace: 88 (grace@example.com) |
Behind the scenes
How TypeScript processes this code
TypeScript checks types and emits JavaScript. Type annotations are removed before execution.
Cost and common mistakes
Type checking has no runtime cost. The describe call is O(1).
- Interfaces exist only at compile time. They are erased from the JavaScript, so they cannot validate data that arrives at runtime, such as a JSON response.
- An optional property can be undefined; read it with ?? or a check before using it as a string.
Try it yourself
Add an optional year: number property and show it in describe.
Reveal answer and reasoning
Add year?: number to Student and format student.year ?? "unknown" in the returned string.