Defining Interfaces
Create clear contracts for your data. Learn how interfaces help objects, functions, and applications stay organized as your code grows.
interface Developer {
name: string;
language: string;
level: number;
}
const moe: Developer = {
name: "Moe",
language: "TypeScript",
level: 7
};
console.log(moe.name);
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.
interface Developer {
name: string;
language: string;
level: number;
}
const moe: Developer = {
name: "Moe",
language: "TypeScript",
level: 7
};
console.log(moe.name);The Developer interface describes what a developer object must contain. TypeScript checks the object against that structure.
Make Sure Important Data Is Present
By default, every property declared in an interface is required. Leaving one out produces a TypeScript error.
interface Course {
title: string;
lessons: number;
}
const course: Course = {
title: "TypeScript"
// Error: lessons is missing
};To fix the error, provide the missing property:
const course: Course = {
title: "TypeScript",
lessons: 11
};This makes interfaces useful when your application depends on a predictable data structure.
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.
interface Developer {
name: string;
language: string;
website?: string;
}
const moe: Developer = {
name: "Moe",
language: "TypeScript"
};
console.log(moe.website);Since website is optional, it can be missing. Always account for undefined when using an optional value.
if (moe.website !== undefined) {
console.log(moe.website);
} else {
console.log("No website provided.");
}Protect Values That Should Stay Consistent
Use readonly when a property should not be reassigned after an object has been created.
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.
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 Developer {
name: string;
level: number;
}
function introduce(person: Developer): void {
console.log(
person.name + " is at level " + person.level
);
}
introduce({ name: "Moe", level: 7 });This is especially helpful when several functions need to work with the same kind of data.
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 Developer {
name: string;
greet(): void;
}
const moe: Developer = {
name: "Moe",
greet(): void {
console.log("Hello from " + this.name);
}
};
moe.greet();Here, the interface requires every Developer to provide a callable greet() method.
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.
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);The Developer interface inherits name from Person and adds its own properties.
Create Collections of Consistent Objects
You can combine an interface with an array to ensure that every element follows the same structure.
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);
}This pattern is useful for lists of users, lessons, products, or any collection of structured records.
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.
// 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.
Build a Developer Profile Contract
Let’s combine interface inheritance, optional properties, methods, and functions in one example.
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);By describing the object first, you make it easier to create consistent profiles and catch mistakes while writing code.
Build a Developer Profile Contract
Create a reusable interface that describes a developer profile, then build a working object that follows it.
Your Mission
- Create a
Personinterface with a requirednameproperty. - Create a
Developerinterface that extendsPerson. - Add required
languageandlevelproperties. - Add an optional
websiteproperty. - Add a
greet()method that prints a personalized greeting. - Create a developer object for Moe or yourself and display its profile.
- Experiment with a missing property or incorrect type to see TypeScript catch the mistake.
id property, then try to reassign it and examine the compiler’s response.Design Your Developer Interface!
Edit the interface, customize the developer, and run the code. The sandbox checks TypeScript types before executing the compiled JavaScript.
Preparing TypeScript sandbox…
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 CompletedSeven 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!
