TypeScript: TypeScript interface (interface)

Last updated: 2026-08-26

An interface is the core way TypeScript defines the structure of an object—it describes "which properties and methods an object must have," but does not provide an implementation.

1. Basic Syntax of Interfaces

(1) Define an interface

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

(2) Using the Interface

TYPESCRIPT
let user: User = {
  name: "Charlie",
  age: 20,
  email: "xiaoming@example.com"
};

(3) Interfaces as Function Parameters

TYPESCRIPT
function greet(user: User): string {
  return `Hello,${user.name}!How old are you this year?${user.age} years old。`;
}

console.log(greet({ name: "Diana", age: 22, email: "hong@example.com" }));

Output:

TEXT 📖 Display only
Hello,Diana!How old are you this year?22 years old。

(4) Methods for Describing Interfaces

Interfaces can describe not only properties but also method signatures:

TYPESCRIPT
interface Animal {
  name: string;
  speak(): string;
  move(distance: number): void;
}

let dog: Animal = {
  name: "Wangcai",
  speak() { return "Woof!"; },
  move(distance) { console.log(`${this.name} Moved ${distance}m`); }
};

console.log(dog.speak());   // "Woof!"
dog.move(10);               // "Wangcai Moved 10m"


2. Optional Properties and Read-Only Properties

(1) Optional Attribute ?

TYPESCRIPT
interface Config {
  host: string;
  port: number;
  debug?: boolean;     // Optional
  timeout?: number;    // Optional
}

// Optional attributes may be omitted.
let config: Config = { host: "localhost", port: 3000 };
let config2: Config = { host: "localhost", port: 3000, debug: true };

(2) Read-Only Property readonly

TYPESCRIPT
interface Point {
  readonly x: number;
  readonly y: number;
}

let point: Point = { x: 1, y: 2 };
// point.x = 10;  // ❌ Read-only properties cannot be modified.

(3) ReadonlyArray and Interfaces

TYPESCRIPT
interface TodoList {
  readonly name: string;
  readonly items: readonly string[];   // items Both the array itself and its contents are read-only.
}

let todo: TodoList = {
  name: "Today's Tasks",
  items: ["Write code", "Test", "Deployment"]
};

// todo.items.push("New Task");  // ❌ Read-only arrays cannot be modified.
// todo.name = "Tomorrow's Tasks";     // ❌ Read-only properties cannot be modified.


3. Interface Inheritance (extends)

Interfaces can inherit from other interfaces via extends to enable type composition and reuse:

(1) Single Inheritance

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

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

let emp: Employee = {
  name: "Charlie",
  age: 28,
  employeeId: "E001",
  department: "Engineering Department"
};

(2) Multiple Inheritance

An interface can inherit from multiple interfaces at the same time:

TYPESCRIPT
interface Serializable {
  serialize(): string;
}

interface Loggable {
  log(message: string): void;
}

interface Entity extends Serializable, Loggable {
  id: number;
}

let item: Entity = {
  id: 1,
  serialize() { return JSON.stringify({ id: this.id }); },
  log(message) { console.log(`[${this.id}] ${message}`); }
};

(3) Override Properties

A child interface can override the property types of a parent interface, but it must be compatible:

TYPESCRIPT
interface Base {
  data: string | number;
}

interface Derived extends Base {
  data: string;   // ✅ Narrowing — string is a subtype of string | number
}

▶ Example: Building Hierarchical Types Using Inheritance

TYPESCRIPT
// Basic Interfaces
interface Shape {
  color: string;
}

// Extension Interface
interface Square extends Shape {
  sideLength: number;
}

interface Circle extends Shape {
  radius: number;
}

// Usage
let square: Square = { color: "Red", sideLength: 10 };
let circle: Circle = { color: "Blue", radius: 5 };

function describeShape(shape: Shape): string {
  return `One${shape.color}the graphic`;
}

console.log(describeShape(square));  // "A red shape"
console.log(describeShape(circle));  // "A blue shape"
▶ Try it Yourself

Output:

TEXT 📖 Display only
One Red graphic
One Blue graphic


4. Declaration Merging

A unique feature of interfaces—interfaces with the same name automatically merge their properties:

(1) Basic Merge

TYPESCRIPT
interface Window {
  title: string;
}

interface Window {
  count: number;
}

// Equivalent to:
// interface Window {
//   title: string;
//   count: number;
// }

let win: Window = { title: "Main Window", count: 3 };

(2) Rules for Merging

TYPESCRIPT
interface Calculator {
  compute(a: number, b: number): number;
}

interface Calculator {
  compute(a: string, b: string): string;
}

// After the merger compute There are two overloads
let calc: Calculator = {
  compute(a: any, b: any): any {
    return a + b;
  }
};

console.log(calc.compute(1, 2));        // 3
console.log(calc.compute("a", "b"));    // "ab"

(3) Practical Use: Extending Third-Party Types

TYPESCRIPT
// For the built-in Window Adding Custom Properties to an Interface
interface Window {
  myCustomProperty: string;
}

// It is now safe to use
// window.myCustomProperty = "hello";  // ✅
💡 This is why you use interface instead of type to extend the types of third-party libraries— type does not support type union, but interface does.



5. Index Signatures and Interfaces

Index signatures can also be used in interfaces:

TYPESCRIPT
interface StringMap {
  [key: string]: string;
}

let translations: StringMap = {
  hello: "Hello",
  goodbye: "Goodbye",
  thanks: "Thank you"
};

// Add a new key-value pair
translations["sorry"] = "I'm sorry";

When an index signature and known attributes coexist, the types of the known attributes must be compatible:

TYPESCRIPT
interface Config {
  [key: string]: string | number;
  host: string;       // ✅ string is a subtype of string | number
  port: number;       // ✅ number is a subtype of string | number
  // debug: boolean;  // ❌ boolean No string | number subtypes of
}


6. The Difference Between Interfaces and Type Aliases

Both interfaces and types can define object types, but there are the following differences:

Feature interface type
Object Type ✅ Primary Use ✅ Can Also Be Used For
Statement Merging ✅ Supported ❌ Not Supported
Inheritance extends & Cross-type
Union Type ❌ Cannot be defined directly type A = B | C
Aliases for Basic Types ❌ Not allowed type ID = string
Computed Properties ❌ Not supported ✅ Supported
instanceof ✅ class implements ❌ Cannot

(1) When to use an interface

(2) When to use type

📌 Recommendation: Use interface for object types and type for union types and operations on advanced types. The two are not mutually exclusive and can be used together in the same project.


▶ Example: Optional and Readonly Properties in Practice

TYPESCRIPT
interface UserProfile {
  readonly id: number;
  name: string;
  email: string;
  nickname?: string;
  readonly createdAt: Date;
}

let user: UserProfile = {
  id: 1,
  name: "Charlie",
  email: "charlie@example.com",
  createdAt: new Date()
};

user.name = "Diana";             // ✅ name is mutable
// user.id = 2;                  // ❌ readonly property
console.log(user.nickname);      // undefined (optional)
▶ Try it Yourself

Output:

TEXT 📖 Display only
undefined

▶ Example: Extending Interfaces for Type Composition

TYPESCRIPT
interface Timestamped {
  createdAt: Date;
  updatedAt: Date;
}

interface Owned {
  ownerId: number;
  ownerName: string;
}

interface Article extends Timestamped, Owned {
  title: string;
  content: string;
}

let article: Article = {
  title: "Hello TypeScript",
  content: "TypeScript is great...",
  createdAt: new Date(),
  updatedAt: new Date(),
  ownerId: 1,
  ownerName: "Charlie"
};

console.log(`${article.ownerName}: ${article.title}`);
▶ Try it Yourself

Output:

TEXT 📖 Display only
Charlie: Hello TypeScript

❓ FAQ

Q Which should I use—interface or type?
A A simple rule of thumb: use interface to define the "shape of an object," and use type to define a "type alias" or "union type." If your team already has a convention, just follow it. In 90% of cases, the two are equivalent, so don't overthink it.
Q Can an interface inherit a type defined by type?
A Yes. interface extends can inherit any object type alias defined by type. Conversely, type can also combine interfaces using cross-types &. The two are fully interoperable.
Q What are the risks of declaration merging?
A Declaration merging is a feature of interfaces, but it also poses a potential risk—if two interfaces with the same name have properties that share the same name but differ in type, a compilation error will occur. In actual development, declaration merging is primarily used to extend the type definitions (.d.ts) of third-party libraries; you should avoid defining interfaces with the same name in your day-to-day code.
Q Can an interface describe a function type?
A Yes, but it’s generally more natural to use type. interface Fn { (a: string): number } is equivalent to type Fn = (a: string) => number, and the latter is more concise and intuitive. We recommend using type for function types.

📖 Summary

📝 Exercises

  1. Basic Problem (Difficulty ⭐): Define the Book interface (title, author, pages, isbn?), create two book objects, and print them. Note that isbn is an optional property.
  2. Advanced Problem (Difficulty ⭐⭐): Define the Shape base interface (with the color and area methods), then define Circle and Rectangle so that they each inherit from Shape and add their own properties. Write a function that takes a parameter of type Shape and calls the area method.
  3. Challenge (Difficulty: ⭐⭐⭐): Use a declaration to add a last(): T | undefined method to the built-in Array<T> interface. Then call this method on an actual array, and consider why this requires a module declaration.
Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏