Codectionary / Developer documentation / TypeScript

Interfaces

Interfaces in TypeScript define the structure of objects by specifying property names and their types. They act as contracts that ensure objects conform to specific shapes, providing type safety and better IDE support. Interfaces can be extended, merged, and used to type-check function parameters, return values, and object literals.

Before you start: Basic Types ยท Variables: var, let, const

Syntax

interface Name {
  property: type;
}

Breaking down the syntax

interface
Names an object type.
property: type
Describes a member and its expected type.
?
Marks a property as optional.

How it works

An interface describes the shape an object should have. TypeScript checks that shape before execution; the interface does not become a runtime validator.

Describe

List the expected members.

Check

The compiler compares values with the shape.

Execute

The resulting JavaScript runs without the interface declaration.

Examples

A small working example

Follow the values through this example, then change one input.

interface Lesson {
  title: string;
  completed?: boolean;
}
const lesson: Lesson = { title: "Interfaces" };
console.log(lesson.title);
  1. title is required.
  2. completed may be absent.
  3. The interface is removed when transpiling.

Basic Interface

Defining a simple interface for object structure.

interface User {
  id: number;
  name: string;
  email: string;
  age: number;
}

const user: User = {
  id: 1,
  name: "Alice",
  email: "alice@example.com",
  age: 25
};

function displayUser(user: User) {
  console.log(`${user.name} (${user.email})`);
}

displayUser(user);

Optional Properties

Using optional properties and readonly modifiers.

interface Product {
  id: number;
  name: string;
  price: number;
  description?: string;  // Optional
  readonly category: string;  // Cannot be modified
}

const product: Product = {
  id: 101,
  name: "Laptop",
  price: 999.99,
  category: "Electronics"
};

// product.category = "Tech"; // Error: readonly property
console.log(product);

// Using optional property
if (product.description) {
  console.log(product.description);
}

Extending Interfaces

Creating new interfaces by extending existing ones.

interface Person {
  name: string;
  age: number;
}

interface Employee extends Person {
  employeeId: number;
  department: string;
  salary: number;
}

const employee: Employee = {
  name: "Bob",
  age: 30,
  employeeId: 12345,
  department: "Engineering",
  salary: 75000
};

// Multiple inheritance
interface Manager extends Employee, Person {
  teamSize: number;
  managerId: number;
}

console.log(employee);

Function Types

Using interfaces to define function signatures.

interface MathOperation {
  (a: number, b: number): number;
}

const add: MathOperation = (a, b) => a + b;
const subtract: MathOperation = (a, b) => a - b;

console.log(add(5, 3));      // 8
console.log(subtract(10, 4)); // 6

// Interface for object with methods
interface Calculator {
  add(a: number, b: number): number;
  subtract(a: number, b: number): number;
  multiply(a: number, b: number): number;
}

const calc: Calculator = {
  add: (a, b) => a + b,
  subtract: (a, b) => a - b,
  multiply: (a, b) => a * b
};

Best practices

  • Use interfaces for object shapes and type for unions/intersections
  • Prefix interface names with "I" only if your team convention requires it
  • Mark properties as readonly when they shouldn't be modified after creation
  • Use optional properties (?) for truly optional fields
  • Extend interfaces when creating specialized versions of base types
  • Document interfaces with JSDoc comments for better IDE tooltips

Runtime & versions

Compiled to JavaScript. Feature availability depends on the language and runtime version used by your project; consult the official reference below.

TypeScript Handbook

When should I use this?

Name object contracts shared by functions and components.

Common mistakes

A common trap

A required property must be present.

Incorrect

interface User { name: string }
const user: User = {};

Corrected

interface User { name: string }
const user: User = { name: "Ada" };

Compare approaches

  • Interface: Object shapes that may be extended or declaration-merged.
  • Type alias: Name a type, including a union or primitive.

Explore deeper

Runtime data still needs checking

Type annotations are erased. Validate untrusted API responses at runtime instead of relying on a type assertion.

Specifications & further reading