WHAT'S NEW
TypeScript · Lesson 07 of 11

Defining Interfaces

Create clear contracts for your data. Learn how interfaces help objects, functions, and applications stay organized as your code grows.

Object Contracts Optional Properties Readonly Extending Interfaces
● ● ●   interfaces.ts
interface Developer {
  name: string;
  language: string;
  level: number;
}

const moe: Developer = {
  name: "Moe",
  language: "TypeScript",
  level: 7
};

console.log(moe.name);
CONSOLE OUTPUT
> Ready to run…
01 / What Is an Interface?

Give Your Objects a Clear Structure

In the previous lesson, you created objects and used type aliases to describe their properties. An interface gives you another way to define the shape an object should follow.

Think of an interface as a contract: any value assigned to that interface must provide the required properties with compatible types.

first-interface.ts
interface Developer {
  name: string;
  language: string;
  level: number;
}

const moe: Developer = {
  name: "Moe",
  language: "TypeScript",
  level: 7
};

console.log(moe.name);
Console Output:
Moe

The Developer interface describes what a developer object must contain. TypeScript checks the object against that structure.

Remember: Interfaces exist for type checking. They do not create objects or remain as JavaScript interfaces when your code runs.
02 / Required Properties

Make Sure Important Data Is Present

By default, every property declared in an interface is required. Leaving one out produces a TypeScript error.

required-properties.ts
interface Course {
  title: string;
  lessons: number;
}

const course: Course = {
  title: "TypeScript"
  // Error: lessons is missing
};

To fix the error, provide the missing property:

correct-course.ts
const course: Course = {
  title: "TypeScript",
  lessons: 11
};

This makes interfaces useful when your application depends on a predictable data structure.

03 / Optional Properties

Allow Flexibility Where It Makes Sense

Some information might not be available for every object. Add a question mark to mark a property as optional.

optional-interface.ts
interface Developer {
  name: string;
  language: string;
  website?: string;
}

const moe: Developer = {
  name: "Moe",
  language: "TypeScript"
};

console.log(moe.website);
Console Output:
undefined

Since website is optional, it can be missing. Always account for undefined when using an optional value.

checking-optional-values.ts
if (moe.website !== undefined) {
  console.log(moe.website);
} else {
  console.log("No website provided.");
}
Console Output:
No website provided.
04 / Readonly Properties

Protect Values That Should Stay Consistent

Use readonly when a property should not be reassigned after an object has been created.

readonly-interface.ts
interface Developer {
  readonly id: number;
  name: string;
}

const moe: Developer = {
  id: 101,
  name: "Moe"
};

moe.name = "Moe M.";

// TypeScript error:
// moe.id = 202;

TypeScript allows the name to change but rejects reassignment of id. Keep in mind that readonly is a compile-time restriction, not automatic runtime freezing.

05 / Interfaces with Functions

Pass Consistent Data to Your Functions

Functions can accept parameters typed with an interface. That means every object passed to the function must have the required properties.

interface-parameters.ts
interface Developer {
  name: string;
  level: number;
}

function introduce(person: Developer): void {
  console.log(
    person.name + " is at level " + person.level
  );
}

introduce({ name: "Moe", level: 7 });
Console Output:
Moe is at level 7

This is especially helpful when several functions need to work with the same kind of data.

06 / Methods in Interfaces

Describe What an Object Can Do

Interfaces can define methods as well as properties. A method signature specifies the expected parameters and return type.

interface-methods.ts
interface Developer {
  name: string;
  greet(): void;
}

const moe: Developer = {
  name: "Moe",
  greet(): void {
    console.log("Hello from " + this.name);
  }
};

moe.greet();
Console Output:
Hello from Moe

Here, the interface requires every Developer to provide a callable greet() method.

07 / Extending Interfaces

Build on an Existing Structure

One of the most useful interface features is extends. It lets you create a new interface that inherits properties from another interface.

extends.ts
interface Person {
  name: string;
}

interface Developer extends Person {
  language: string;
  level: number;
}

const moe: Developer = {
  name: "Moe",
  language: "TypeScript",
  level: 7
};

console.log(moe.name);
console.log(moe.language);
Console Output:
Moe TypeScript

The Developer interface inherits name from Person and adds its own properties.

Tip: Extending interfaces can help you reuse shared structures without repeatedly writing the same properties.
08 / Interfaces and Arrays

Create Collections of Consistent Objects

You can combine an interface with an array to ensure that every element follows the same structure.

interface-array.ts
interface Developer {
  name: string;
  level: number;
}

const developers: Developer[] = [
  { name: "Moe", level: 7 },
  { name: "Jordan", level: 5 }
];

for (const developer of developers) {
  console.log(developer.name);
}
Console Output:
Moe Jordan

This pattern is useful for lists of users, lessons, products, or any collection of structured records.

09 / Interfaces vs. Type Aliases

Two Useful Ways to Describe Types

You already learned how to define an object structure using a type alias. Interfaces can describe similar structures, but the two features are not identical.

two-approaches.ts
// Interface approach
interface Developer {
  name: string;
}

// Type alias approach
type DeveloperProfile = {
  name: string;
};

Both can describe object shapes. Interfaces support declaration merging, meaning compatible declarations with the same interface name can be combined. Type aliases can also describe unions, tuples, and other types that are not simply object contracts.

Practical advice: Use either for straightforward object structures. Interfaces are often convenient for extensible object contracts; type aliases are particularly useful for unions and more complex type expressions.
10 / Putting It Together

Build a Developer Profile Contract

Let’s combine interface inheritance, optional properties, methods, and functions in one example.

developer-profile.ts
interface Person {
  name: string;
}

interface Developer extends Person {
  language: string;
  level: number;
  website?: string;
  greet(): void;
}

const moe: Developer = {
  name: "Moe",
  language: "TypeScript",
  level: 7,
  website: "mc0de.com",
  greet(): void {
    console.log("Hello from " + this.name);
  }
};

moe.greet();
console.log(moe.language);
Console Output:
Hello from Moe TypeScript

By describing the object first, you make it easier to create consistent profiles and catch mistakes while writing code.

🚀 mC0de Challenge

Build a Developer Profile Contract

Create a reusable interface that describes a developer profile, then build a working object that follows it.

Your Mission

  1. Create a Person interface with a required name property.
  2. Create a Developer interface that extends Person.
  3. Add required language and level properties.
  4. Add an optional website property.
  5. Add a greet() method that prints a personalized greeting.
  6. Create a developer object for Moe or yourself and display its profile.
  7. Experiment with a missing property or incorrect type to see TypeScript catch the mistake.
Extra challenge: Add a readonly id property, then try to reassign it and examine the compiler’s response.
💻 Interactive TypeScript Sandbox

Design Your Developer Interface!

Edit the interface, customize the developer, and run the code. The sandbox checks TypeScript types before executing the compiled JavaScript.

Console Output
Lesson 07 Recap

What You’ve Learned

You’re Writing More Reliable TypeScript!

You can now:

  • Define object structures using interfaces.
  • Understand required and optional properties.
  • Protect properties with readonly.
  • Use interfaces to type function parameters.
  • Define methods inside interfaces.
  • Extend interfaces to reuse shared structures.
  • Combine interfaces with arrays of objects.
  • Recognize the differences between interfaces and type aliases.

Next up: Classes — learn how to create reusable blueprints for objects that combine data and behavior!

Your Learning Journey

0 / 11 Completed

Seven lessons in! Keep building your TypeScript skills, one concept at a time.

🎉

You’re Building Better Code!

You’ve learned how to define interfaces, require or omit properties, extend object contracts, and create reusable structures. You’re ready to take the next step toward object-oriented TypeScript!

PIX0
</> {} JS 01
0101 </> CSS JS HTML PIX0 const {} 1010 async mC0de function return 0101 <div> 1010 PIX0 CSS JS HTML const {} 0101 mC0de
PIX0 // WORLD OF CODE
PIX0 IS PREPARING SOMETHING AWESOME FOR YOU 0%