TypeScript Classes Implementing Interfaces
In this guide we're going to examine how to implement interfaces in classes, including two processes that allow for class implementation.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

So far in this section on object-oriented programming we've talked extensively about interface's about classes and what we're going to do now is talk about how we can actually bring them together. And this one is going to be a very important lesson to go through because once you get into angular development some of the code that you're going to be seeing today in this guide is going to be used extensively in order to build angular 2 programs and that is being able to take interfaces and then have classes actually implement those interfaces we've worked with interfaces and functions. And that's definitely an important concept and it was a good base case for us. However in real-world programs with angular usually are going to be creating an interface and then that is going to be applied on top of a class.

So in this guide, I'm going to go through two different ways that interfaces can work with classes. The first is going to be a very basic kind of a minimalistic way that you can enforce data types. And then the second one is going to be the full implementation.

So this first one I'm going to borrow what we did for our basic interface for users. So I'm going to create an interface for a user and I'm going to even use the same values of say email string and then we have a first name which is going to be a data type string. It's going to be optional. and then the last name is also going to be optional. This is going to be of data type string as well. And now I'm going to create a class in this class is going to be an admin class and inside of this we're going to add a new parameter in this parameter is going to be called role and it's going to be a string. This is a pretty common type of workflow code where you have an admin who has a role now inside of this class. We're going to have a constructor and the constructor is going to take the e-mail which is a string data type and then it is going to assign this .role to admin. And if you remember what this means is that when we create a real-world object out of admin it gets assigned to whatever that specific admin's role is. So if we have an admin named Joe then it's getting assigned to it could say, Joe, .role or if we have one name Tiffany it's going to be Tiffany's role. This means that it is speaking specifically to the object that is going to be constructed.

Interface User {
  Email: string;
  firstName? : string;
  lastName? : string;
}

class Admin {
  role : string;
  constructor(public email : string) {
    this.role = ‘Admin’;
  }
}

Now if I come down and take our profile function and here I'm going to pass in just like we did before this is going to be of data type user which is taking our interface for user. And it's going to be essentially foreseen that value. And it's going to return a string. And here we're going to say return and you use string interpolation for this one and I'll say welcome and then put a $ curly brackets and inside of this, we'll say user.email. Now in order to run this code, we first have to instantiate an admin user so I could say var and let's just go with Joe. That was our guy we said was going to be an admin so we're going to say Joe equals new admin. And his email address is going to be Joe@example.com and now we can say console.log and we can print out Joe.role. And if the syntax is right this should work.

function profile(user: User) : string {
  return `Welcome, ${user.email}`;
}

var joe = new Admin(‘joe@example.com’);
console.log(joe.role);

This was number 025_interface_classes. And you can see it prints out Joe's role as being an admin. So if you're wondering kind of how this all works this is having interfaces that are loosely connected with classes and that's why I said we're going to talk about two ways that classes and interfaces can work together. This is where it's kind of loose and the reason why it is, is the connection is actually happening here at the profile site. And so the profile is saying that if you notice this is the only thing that says user in it. So we're saying that this profile is of type user.

So how exactly did this work with that? The kind of magic behind this one is the fact that admin had to put in the parameters needed so admin took in this string right here and it has an e-mail data type if we did not have an e-mail data type right there. That means that this would not have a valid contract. Remember the interface is the contract for your program and it has to have certain requirements because it has an e-mail data type e-mail attribute right there. Then it falls in line and it means that this interface is able to work with the admin class. So like I said that is one way of doing it and I'm going to say loosely connected interface with class just so you have access to this in the show notes and in the source code. And this is going to be a direct implementation.

So now they have a good idea of you know one way of doing it. Let's look at a second way and this way is going to be a little bit more of a kind of the common way you'll see when we talk about angular development and I'm even going to use the syntax and kind style guide used. So usually what you'll see is an interface and we're going to create an interface I wanted to do something very practical so let's say that we're building some kind of social media application in angular then we're going to want to have an interface. And then also a class for posts. So you know like blog posts or anything like that.

So I'm going to say interface and the convention to follow is whenever you have an interface that's directly connected to a class. You put the class name but right before it you put the letter I. So it's like it's saying that this is the interface for post. So if you have a post class that is going to implement the interface name should be I post an inside of this interface. We're going to put a title which is going to be of type string and then we're going to have a body which is also going to be of type string.

interface IPost {
  title: string;
  body: string;
}

Now what we can do is have a class. So this is going to be a class right here and this is going to be a class post and inside of this, we're going to have a few attributes. And in order to get this so it's a direct match. We're going to have title and body. Now we also have to have a keyword where we say class posts implements I post. And so what this is. This is where the direct connection comes in where we're saying that class most implements IPosts. And then we have these values here so that we are following along with the contract. Now we're going to have a constructor and the constructor. It's not going to take a title in a body. Instead, it's going to take a post. So it's going to take I post and the way that this works is we're saying that the contract of this is going to accept a title and a body. So our constructor is going to take something that follows the pattern. So anything that our constructor takes in when we create a post has to contain a title in a body attribute. And so inside of it, I'm going to do this. And the reason why I keep on talking about what this is because I've worked with students for a number of years and this seems to be one of the more confusing things in development especially JavaScript development. So just once again this is going to reference the value that is created when we actually create one of these class objects and when we create a post the title of that created post is going to be what is assigned right here.

So we're going to say this title is equal to post title and we have access to the word post here because this is going to be the object that comes in right here and we're going to say the same thing for body if I can spell it right. And that's going to be it for the constructor. And additionally I want to add a method inside of here so I can say print post it's going to be pretty basic it's not going to be taking arguments that because it's in this class we actually have access to the title and the body attributes which is and so inside of here we can do console.log this title and we can do this stop body. Now. In order for this to work, I’m going to say var post equals new post. So I'm creating a post here and now I'm going to pass in a JavaScript object. So I'm going to create curly braces and inside of this all say title, which will equal “my great title” and followed by a comma followed by a body and say “some content” ended off with a colon. And now I want to do a few things. I'm going to print out I'm going to give us some space. You can see right in the middle. So here I'm going to console log out the value of the post title. And also the Post body and I'm then going to call the method something as a post.print post and follow it up with parentheses because it is a function and this should be it.

class Post implements IPost {
  title: string;
  body: string;

constructor(post: IPost) {
    this.title = post.title);
    this.body = post.body;
  }

  printPost() {
    console.log(this.title);
    console.log(this.body);
  }
}

var post = new Post({ title: “My Great Title”, body: “Some content”});
console.log(post.title);
console.log(post.body);
post.printPost();

So we know that this one works because I believe we ran this one. And so now what we should get is we should get my great title and some content. Print it out twice one for these two console log statements that are grabbing just the attributes and then once each for this print post which should print both of these values so that saved. Moment of Truth that looks like that worked. And running it again you can see that, that all works perfectly. So this is how you can have a direct implementation of an interface with a class. You use the class name. You say that it implements whatever interface you want it to implement. And then inside of this the value or the data type that you're saying that you want the argument to be is going to be whatever the actual interface is. So this is what makes it possible for us to know that it's going to take in a title in a body. And if you are wondering why it seems like there's some duplicate code here a lot of that comes down to the fact that we are being very explicit on what these classes and what these different objects inside of the program are going to contain. So we're saying that a post is going to contain a title and the body and it's going to follow these various interface rules.

Now if you're coming from a language like Ruby This may seem like overkill. But also remember in languages like Ruby and Python you can accomplish a lot more functionality in a shorter amount of code if you're coming from a language like Java that implements interfaces. This may seem like a very short amount code because this is actually pretty precise compared to the way you have to build Java classes and interfaces so it's kind of a cross between the two. And in my opinion, you really get a nice combination of both worlds. You get a lot of the good type checking and some of the things that come along with the more formal languages like Java but you also get to have some nice clean easy to read code from languages like Ruby or Python.

So these are two ways that you can directly and loosely connect interfaces with classes in typescript.

Resources