What The H*** is Interface in Typescript😆

What The H*** is Interface in Typescript😆

If you see the long reading time for this article, don't worry 😉. I have written this awesome😎 article with many code examples😃 (with some nice Meme😂 as well); it's not just theory🔥.

So, buckle up🚀. We will begin our incredible journey🛣

let's do this


Interface 🤿

Interface helps us keep our programs error-free😋 by providing information about the shape of the data we work with😃. Because the type of information is erased from a TypeScript program during compilation, we can freely add type data using interfaces without worrying about the runtime overhead🥳. wohoo

The TypeScript compiler does not convert interface to JavaScript. It uses interface for type checking. This is also known as duck typing 🦆 or structural subtyping . You will see this on the journey😉.

Let’s consider an object 👇

var person = { 
   FirstName:"Amirul", 
   LastName:"Asyraf", 
   saySomething: ()=>{ return "Tyepscript is Awesome"} 🔥
};

If we consider the signature of the object, it could be −

{ 
   FirstName:string, 
   LastName:string, 
   saySomething()=>string 
}

To reuse the signature across objects we can define it as an interface.

Declaring Interfaces

The interface keyword is used to declare an interface. Here is the syntax to declare an interface 👇

Syntax

interface interface_name { 
}

Example: Interface and Objects

interface Person { 
   firstName:string, 
   lastName:string, 
   saySomething: ()=>string 
} 

var employee: Person = { 
   firstName:"Amirul",
   lastName:"Asyraf", 
   saySomething: ():string =>{
return "Interface is like your strict parent" } 😆
}

The example defines an interface. The employee object is of the type Person. Hence, it will now be binding on the object to define all properties as specified by the interface.

On compiling, it will generate the following JavaScript code👇

//Generated by typescript 4.0.2
var employee = {
    firstName: "Amirul",
    lastName: "Asyraf",
    saySomething: () => {
        return "Interface is like your strict parent";
    }
};

Interfaces are not to be converted to JavaScript. It’s just part of TypeScript😃. If you see the screenshot of TS Playground tool there is no javascript emitted when you declare an interface, unlike a class. So interfaces have zero runtime JavaScript impact.🥳

Screenshot 2020-10-08 at 15.10.13.png

Union Type and Interface

The following example shows the use of Union Type and Interface 👇

interface RunOptions { 
   program:string; 
   commandline: string[ ] | string | (( )=>string); 👈
} 

//commandline as string 
var options:RunOptions = {program:"test1",commandline:"Hello"}; 
console.log(options.commandline)  

//commandline as a string array 
options = {program: "test1", commandline: ["Hello", "World" ]}; 
console.log(options.commandline[0]); 
console.log(options.commandline[1]);  

//commandline as a function expression 
options = {program: "test1", commandline:( )=>{return "**Hello World**"; }}; 

var fn: any = options.commandline; 
console.log(fn());

Its output is as follows −

Hello 
Hello 
World 
**Hello World**

WOW Awesome right 😎


Interfaces and Arrays

Interface can define both the kind of key an array uses and the type of entry it contains. The index can be of type string or type number.

interface namelist { 
   [index: number]: string 
} 

var list2: namelist = ["Asyraf", 5 , "John Doe"] ❌
// Error, 5 is not type string  

interface ages { 
   [index: string]: number 
} 

var agelist: ages; 
agelist["Asyraf"] = 19  ✅
agelist[2] = "nine"

Optional Property

Sometimes, we may declare an interface with excess properties but may not expect all objects to define all the given interface properties.🤔

Interfaces with optional properties are written similar to other interfaces, with each optional property denoted by a ? at the end of the property name in the declaration.🤩

interface IEmployee {
    empCode: number;
    empName: string;
    empDept?: string;  👈
}

let empObj1: IEmployee = {   ✅
    empCode: 1,
    empName: "Steve"
}
// still OK even don't have empDept 🤠

let empObj2: IEmployee = {    ✅
    empCode: 1,
    empName: "Bill",
    empDept: "IT"
}

The advantage👍 of optional properties is that you can describe these possibly available properties while still also preventing the use of properties that are not part of the interface. 😉. For example, had we mistyped the name of the empDept property in IEmployee , we would get an error message❌ letting us know:

See this Live Example


Read-only Properties

If you wanna implement some properties that can't change when an object is first created, you can specify this by putting readonly before the name of the property.

Mehhh😑, code please😆

Ok2 consider this ;

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

You can construct a Point by assigning an object literal. After the assignment, x and y can’t be changed❗️❗️.

let p1: Point = { x: 34, y: 80 };
p1.x = 10;   😯

Wait2

TypeScript also comes with a ReadonlyArray<T> type that is the same as Array<T>🤩 with all mutating methods removed, so you can make sure you don’t change your arrays after creation😉:

let id: number[] = [1, 2, 3, 4];
let roId: ReadonlyArray<number> = a;

roId[0] = 34;  

roId.push(6);  

roId.length = 105;  

newId = roId; 

Open this Live Examples to see the Error Expalantions !!

another example 🤩

interface Citizen {
     name: string;
👉 readonly SSN: number;
}

let personObj: Citizen  = { SSN: 110364739, name: 'Amirul Asyraf' }

personObj.name = 'John Cena';  ✅ 💪
personObj.SSN = '333666888';  ❌

Extending Interfaces

An interface can be extended by other interfaces🤩. In other words, an interface can inherit from other interfaces. Typescript allows an interface to inherit from multiple interfaces.🔥

Use the extends keyword to implement inheritance among interfaces.

Syntax: Single Interface Inheritance

Child_interface_name   extends   super_interface_name

Syntax: Multiple Interface Inheritance

Child_interface_name   extends   super_interface1_name, 
super_interface2_name,…,super_interfaceN_name
// and so on

Show me the Code, please 🙏 Ok2

Example: Simple Interface Inheritance

interface Person { 
   age: number 
} 

interface Musician extends Person { 👈
   instrument: string 
} 

var drummer = <Musician>{ }; 
drummer.age = 27 ✅
drummer.instrument = "Drums"

Example: Multiple Interface Inheritance

interface IParent1 { 
   v1: number 
} 

interface IParent2 { 
   v2: number 
} 
                           👇         👇
interface Child extends IParent1, IParent2 { } 
var Iobj: Child = { v1: 12, v2: 23} 
console.log("value 1: "+ this.v1 + " value 2: "+ this.v2)

The output of the above code is as follows −

value 1: 12   value 2: 23

Implementing Interface

Similar to languages like Java and C#, interface in TypeScript can be implemented with a Class🔥. The Class implementing the interface needs to strictly conform to the structure of the interface.

interface IVehicle {
    name: String,
    doors: Number
}

class Car implements IVehicle {
    name: String = "Tesla";  🔥
    doors: Number = 4;
    color: String = "Black"; 😎

    getDetails(): String {
        return `Name : ${this.name}, Doors: ${this.doors}, Color: ${this.color}`
    }
}

const car: Car = new Car(); // instance of Car Class
console.log(car.name);
console.log(car.doors);
console.log(car.color);
console.log(car.getDetails());

Output :

Tesla
4
Black
Name : Tesla, Doors: 4, Color: Black

Interface Extending classes

Interface can extend a class. It inherits a member of the class if it extend.

For example:

class Boy {
    name: String;
}

interface IStudent extends Boy {
    printDetails(): void;
}

class Student implements IStudent {
    name: String;

    constructor(name: String) {
        this.name = name;
    }

    printDetails() {
        console.log(this.name);
    }
}

let student = new Student("Asyraf");

student.printDetails();

In this example, we have a class Student that implements interface IStudent. IStudent extends class Boy. We have to add both name and printDetails in Student class🤩. If you run it, it will print “Asyraf” as the output😉

MORE ON THIS !!!


Using interface as a function type

To describe a function type with an interface, we give the interface a call signature. This is like a function declaration with only the parameter list and return type given. Each parameter in the parameter list requires both name and type.

Code, please 😑

interface IMsg {
    (name: String, msg: String): void;  👈
};

function morningMsg(name: String, msg: String){
    console.log('Good Morning, '+ name + ', ' + msg);
}

function eveningMsg(name: String, msg: String){
    console.log('Good Evening, ' + name + ', ' + msg);
}

let mMsg: IMsg = morningMsg;
let eMsg: IMsg = eveningMsg;

mMsg('Developers', 'Welcome to our Blog !')
eMsg('Designer', 'Welcome to our Blog !')

Output

Good Morning, Developers, Welcome to our Blog! 👨🏻‍💻👩‍💻
Good Evening, Designer, Welcome to our Blog! 🕺

MORE ON THIS ARTICLE !!!

Indexable Types

JavaScript freely mixes members (foo.x) with indexers (foo['x']), but most programmers👨🏻‍💻👩‍💻 use one or the other as a semantic hint about what kind of access is taking place. TypeScript interfaces can be used to represent what the expected type of an indexing operation is.

interface StringArray {
  [index: number]: string;
}

let myArray: StringArray;
myArray = ["Amirul", "Asyraf"];

let myStr: string = myArray[0]; ✅

Let's Recap 🕺

What do you guys learn so far ??

  1. Declaring Interface
  2. Union Type and Interface
  3. Interfaces and Arrays
  4. Optional property
  5. Read-only Properties
  6. Extending Interface
  7. Implementing Interface
  8. Interface Extending classes
  9. Using interface as a function type
  10. Indexable Types

Finish 🏁

we made it finish

Thanks for finishing it 🙌

You're Awesome 😎

Bookmark and Share it 🤟


note : If you still don't understand yet, don't worry dude. It happens to me all the time😎. I give you another resource to help you🦸‍♂️.

post 1

post 2