Technology · TypeScript
TypeScript Interfaces
Learn how interfaces define object shapes, optional properties, and contracts for cleaner typed code.
TL;DR
- 01Describe the shape of objects using interface declarations.
- 02Mark properties as optional or readonly when needed.
- 03Extend interfaces to reuse and combine type definitions.
Basic Syntax
- Declare an interface using the
interfacekeyword and a PascalCase name.interface User { id: number; name: string; } - Use the interface as a type annotation when declaring variables.
const user: User = { id: 1, name: "Sam" }; - List each property with its name and type inside curly braces.
- Add semicolons or commas between properties — both are valid.
- Group related properties into one interface to describe a single object shape.
Property Modifiers
- Mark a property as optional using a question mark after its name.
interface User { id: number; email?: string; } - Use the
readonlykeyword to prevent a property from being changed later.interface Point { readonly x: number; readonly y: number; } - Combine
readonlywith optional properties for safe configuration objects. - Use index signatures for objects with dynamic keys of the same type.
interface Scores { [name: string]: number; } - Set required properties without modifiers, since required is the default.
Methods
- Define methods inside an interface using the shorthand call syntax.
interface Greeter { greet(name: string): string; } - Add parameter types and return types just like regular function declarations.
- Use arrow function style with a property and function type.
interface Greeter { greet: (name: string) => string; } - Both syntax styles work — pick one and stay consistent across your project.
- Type method overloads by listing multiple call signatures inside the interface.
Extending
- Extend an interface using the
extendskeyword to inherit its properties.interface Animal { name: string; } interface Dog extends Animal { breed: string; } - Extend multiple interfaces by listing them separated by commas.
interface Hybrid extends Animal, Trainable {} - Override inherited properties by redeclaring them with a more specific type.
- Use extension to build small base interfaces into larger composed shapes.
- Merge two interfaces with the same name automatically through declaration merging.
Interface vs Type
- Use interfaces for object shapes and class contracts in most cases.
interface User { id: number; name: string } - Use type aliases for unions, intersections, primitives, and tuples instead.
type Status = "loading" | "success" | "error"; - Only interfaces support declaration merging across multiple files.
- Both support extension, but interfaces use
extendsand types use intersections. - Pick one style per project to keep your codebase consistent.
Tip: Use PascalCase for interface names and skip the old
Iprefix, since modern TypeScript style avoids it.
Warning: Declaration merging can cause unexpected behavior, so avoid reusing interface names across unrelated files.