Logo

dev-resources.site

for different kinds of informations.

TypeScript Interfaces: Crafting Code with Creative Precision

Published at
6/10/2024
Categories
typescript
solid
oop
programming
Author
bilelsalemdev
Categories
4 categories in total
typescript
open
solid
open
oop
open
programming
open
Author
13 person written this
bilelsalemdev
open
TypeScript Interfaces: Crafting Code with Creative Precision

Hello everyone, ุงู„ุณู„ุงู… ุนู„ูŠูƒู… ูˆ ุฑุญู…ุฉ ุงู„ู„ู‡ ูˆ ุจุฑูƒุงุชู‡

In TypeScript, interfaces play a crucial role in defining the shape of objects and providing a contract for their behavior. They allow us to enforce consistency and ensure that our code adheres to a specific structure. Let's explore deeply what interfaces are.

Table of Contents

Introduction to Interfaces

I will take a real world example to explain what interfaces are. Let's say you are building a car. You have a blueprint that defines the structure of the car, such as the number of wheels, the color, the model, etc. This blueprint is like an interface in TypeScript. It defines the shape of an object and enforces certain properties that the object must have.

Creating Interfaces

To create an interface in TypeScript, you use the interface keyword followed by the name of the interface and the properties it should have. An example of an interface that defines the structure of a User object would be great to understand this concept:

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

let user: User = {
    id: 1,
    name: "Bilel salem",
    email: "[email protected]",
    age: 23,
};
Enter fullscreen mode Exit fullscreen mode

Optional Properties

if your user object has this code :

let user: User = {
    id: 1,
    name: "Bilel salem",
    email: "[email protected]",
};
Enter fullscreen mode Exit fullscreen mode

It will throw an error because the age property is missing. So what if I have in my database some users that don't have an age? This is where optional properties come in. You can make a property optional by adding a ? after the property name age in the interface definition:

interface User {
    id: number;
    name: string;
    email: string;
    age?: number;
}
Enter fullscreen mode Exit fullscreen mode

Now, the age property is optional, and you can create a user object without it:

let user: User = {
    id: 1,
    name: "Bilel salem",
    email: "[email protected]",
};
Enter fullscreen mode Exit fullscreen mode

This will not throw an error because the age property is optional.

Readonly Properties

Sometimes, you may want to create an object with properties that cannot be changed after they are set. As an example, let's say you have a Car interface with a model property that should not be changed once it is set. If you try to change the model property after it is set like this:

interface Car {
    model: string;
}

let car: Car = { model: "BMW" };
car.model = "Audi";
Enter fullscreen mode Exit fullscreen mode

this will be correct in TypeScript, but what if you want to prevent this from happening? You can make a property readonly by adding the readonly keyword before the property name in the interface definition:

interface Car {
    readonly model: string;
}

let car: Car = { model: "BMW" };
car.model = "Audi"; // Error: Cannot assign to 'model' because it is a read-only property.
Enter fullscreen mode Exit fullscreen mode

Now, if you try to change the model property after it is set, TypeScript will throw an error.

Extending Interfaces

Interfaces can be extended to create new interfaces that inherit the properties of existing interfaces. This is useful when you want to define a new interface that has all the properties of an existing interface, plus some additional properties. Here's an example of extending an interface:

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

interface UserWithAge extends User {
    age: number;
}

let user: User = {
    id: 1,
    name: "Bilel salem",
    email: "[email protected]",
};

let userWithAge: UserWithAge = {
    id: 1,
    name: "Bilel salem",
    email: "[email protected]",
    age: 23,
};
Enter fullscreen mode Exit fullscreen mode

Implementing Interfaces

Now that you know how to create interfaces, you can use them to enforce a contract on classes. When a class implements an interface, it must provide an implementation for all the properties and methods defined in the interface. Here's an example of implementing an interface User in a class UserImpl:

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

class UserImpl implements User {
    id: number;
    name: string;
    email: string;

    constructor(id: number, name: string, email: string) {
        this.id = id;
        this.name = name;
        this.email = email;
    }
}

class WrongUserImpl implements User {
    id: number;
    name: string;
    email: string;

    constructor(id: number, name: string) {
        this.id = id;
        this.name = name;
    }
}
// Error: Class 'WrongUserImpl' incorrectly implements interface 'User'. Property 'email' is missing in type 'WrongUserImpl' but required in type 'User'.
Enter fullscreen mode Exit fullscreen mode

In this example, the UserImpl class implements the User interface by providing an implementation for the id, name, and email properties. If you try to create a class that implements the User interface but does not provide an implementation for all the required properties, TypeScript will throw an error.

Private Properties

Now that you know how to enforce the classes to behave as you want, you can also enforce the access level of the properties. If you want to remove the access to age property from the user object, you can use the private keyword before the property name in the interface definition:

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

class UserImpl implements User {
    id: number;
    name: string;
    email: string;
    private _age: number;

    constructor(id: number, name: string, email: string, age: number) {
        this.id = id;
        this.name = name;
        this.email = email;
        this._age = age;
    }
}

let user: User = new UserImpl(1, "Bilel salem", "bilelsalemdev#gmail.com", 23);
console.log(user.age);

// Error: Property 'age' is private and only accessible within class 'UserImpl'.
Enter fullscreen mode Exit fullscreen mode

So what if you want to access the age property? You can create a getter method in the class to access the private property:

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

class UserImpl implements User {
    id: number;
    name: string;
    email: string;
    private _age: number;

    constructor(id: number, name: string, email: string, age: number) {
        this.id = id;
        this.name = name;
        this.email = email;
        this._age = age;
    }

    get age(): number {
        return this._age;
    }
}

let user: User = new UserImpl(1, "Bilel salem", "[email protected]", 23);
console.log(user.age); // 23
Enter fullscreen mode Exit fullscreen mode

Conclusion

Interfaces are a powerful feature of TypeScript that allow you to define the shape of objects and enforce a contract on their behavior. They provide a way to ensure consistency and type safety in your code, making it easier to catch errors.

solid Article's
30 articles in total
Favicon
Understanding SOLID Principles with C# (short intro)
Favicon
Open-Closed Principle (OCP)-Part-2
Favicon
The O of SOLID
Favicon
The S of SOLID
Favicon
SOLID Principles
Favicon
Applying Open Closed Principle to Real-World Code
Favicon
Applying Single Responsibility Principle to Real-World Code
Favicon
Line-Perfect Comparison of TodoMVC Apps
Favicon
SOLID Principles in Functional Programming (FP) with examples
Favicon
SOLID Principles in React: The Key to Writing Maintainable Components
Favicon
Template
Favicon
Dependency Inversion Principle
Favicon
Interface Segregation Principle
Favicon
Liskov Substitution Principle
Favicon
Single Responsibility Principle
Favicon
Understanding SOLID Principles with Python Examples
Favicon
Unlearning SOLID: My Path to More Nuanced Code Evaluation
Favicon
SOLID Design Principles in Ruby
Favicon
About the "S" in Solid
Favicon
TypeScript Interfaces: Crafting Code with Creative Precision
Favicon
Application of S.O.D. in frontend development
Favicon
Series Belajar Solid Principle - Liskov Substitution Principle (LSP)
Favicon
Series Belajar Solid Principle - Open Close Principle (OCP)
Favicon
SOLID + ReactJS
Favicon
Series Belajar Solid Principle - Single Responsibility Principle (SRP)
Favicon
Arquitetura hexagonal: a sinergia dos princรญpios de desenvolvimento e boas prรกticas
Favicon
Implementing Dependency Inversion Principle in Nest.js using Abstract Classes
Favicon
Tackling Temporal Dependency in Classes
Favicon
SOLID Principles
Favicon
SOLID Principles: It's That Easy! ๐Ÿ˜ฑ STANDOUT ๐ŸŒŸ with SOLID Principles! ๐Ÿง™โ€โ™‚๏ธโœจ

Featured ones: