Reading — step 1 of 7
Learn
interface describes the shape of an object — what fields it has and what their types are. It's TypeScript's main mechanism for naming and reusing types across your codebase. Without interfaces, you'd be writing the same { name: string; age: number } shape inline in dozens of places.
Defining an interface
interface User {
name: string;
age: number;
email?: string; // optional — may be missing
}
const alice: User = { name: "Alice", age: 30 };
// email is optional, so this is valid
const bob: User = { name: "Bob" };
// ✗ compile error — age is required
Optional and readonly
interface Config {
readonly id: string; // can't be reassigned after creation
timeout?: number; // optional
retries: number; // required
}
const c: Config = { id: "c-1", retries: 3 };
c.id = "c-2"; // ✗ compile error — id is readonly
?— the property may be missing or undefined.readonly— the property can't be reassigned after construction.
Methods
interface Greeter {
name: string;
greet(other: string): string;
// function-property style:
farewell: (other: string) => string;
}
Both method-shorthand and function-property syntax work. They behave subtly differently in strict mode (variance), but for everyday code they're interchangeable.
Index signatures — open dictionaries
interface ScoreMap {
[name: string]: number;
}
const scores: ScoreMap = {
alice: 95,
bob: 80,
};
scores.carol = 70; // OK — any string key, number value
Use when the keys aren't fixed but the value type is uniform.
Extending interfaces
interface Person {
name: string;
}
interface Employee extends Person {
department: string;
salary: number;
}
const e: Employee = {
name: "Alice",
department: "Engineering",
salary: 100_000,
};
You can extend multiple interfaces: interface X extends A, B { ... }. The result has all properties from all parents.
interface vs type — which to use?
Both can describe object shapes:
interface User { name: string; age: number; }
type User = { name: string; age: number; };
90% of the time they're interchangeable. Differences:
interfacesupports declaration merging — if you declare the same interface twice, TypeScript merges the fields. Useful for augmenting library types.typesupports unions, intersections, primitives, computed types — interfaces can't.type ID = string | number; // union — must use type type Pair = [number, number]; // tuple — must use type
Convention: use interface for object shapes you might extend later. Use type for unions, tuples, mapped types, or simple aliases. Either works for ordinary objects.
Excess property checking — gotcha
interface Options { url: string; }
function fetch(opts: Options) { /* ... */ }
fetch({ url: "/x", timeout: 5000 });
// ✗ compile error — 'timeout' is not in Options
Passing an object literal directly with EXTRA properties triggers an error. To opt out: assign the literal to a variable first, OR add an index signature.
Common mistakes
- Forgetting
?on optional fields — TypeScript demands the property if you don't. - Mixing
interfacefor unions —interface ID = string | numberis invalid. Usetype. - Stale interface after API change — if your interface drifts from the actual data shape, types LIE. Keep them in sync, ideally generated from the source of truth.
- Excess property checking surprise — passing extra properties in object literals triggers errors. Assign to a typed variable first if needed.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…