o7planning

TypeScript Interfaces Tutorial with Examples

  1. What is Interface?
  2. Interface is a data type
  3. Optional Field
  4. Read-only Field
  5. The interface extends from other interfaces
  6. Implement interfaces
  7. Function-Type Interface
  8. Array-Type Interface

1. What is Interface?

In TypeScript, an interface is a construct that declares standards. Classes derived from an interface must comply with the standards set by the interface.
There is no interfaces concept in JavaScript, so the TypeScript compiler does not convert interfaces to JavaScript. The interface is used as a tool to check the types in the program.
TypeScript uses the interface keyword to define an interface. Interfaces can include fields, properties, and methods.
interface Greeting {
   name: string;

   sayHello(friendName:string): string; // A method

   sayBye: (friendName: string) => string; // A arrow method
}
In the above example, Greeting is an interface that includes 1 field and 2 methods.
  • name: A field with data type string.
  • sayHello: A regular method with a string parameter, and returns a string.
  • sayBye: A Lambda method with a string parameter, and returns a string. (Lambda methods are also known as arrow methods).

2. Interface is a data type

The interface is a data type, and you can create objects directly. The created objects must implement all the fields, properties, and methods declared in the interface.
For easy understanding, see the example:
interface_ex1.ts
interface Greeting {
    name: string;
    sayHello(friendName: string): string; // A method
    sayBye: (friendName: string) => string; // A arrow method
}
function interface_ex1_test() {
    // Create an object:
    var enPerson1: Greeting = {
        name: "John",
        sayHello: function (friendName: string): string {
            return "Hello " + friendName;
        },
        sayBye: function (friendName: string): string {
            return "Good Bye";
        }
    };
    // Create an object
    var vnPerson1: Greeting = {
        name: "Tran",
        sayHello: function (friendName: string): string {
            return "Xin Chao " + friendName;
        },
        sayBye: function (friendName: string): string {
            return "Tam biet " + friendName;
        }
    };
    // Test objects:
    console.log(enPerson1.name); // John
    console.log(enPerson1.sayHello("Tom")); // Hello Tom

    console.log(vnPerson1.name); // Tran
    console.log(vnPerson1.sayBye("Jerry")); // Tam Biet Jerry
}
interface_ex1_test(); // Call the function.
Output:
John
Hello Tom
Tran
Tam biet Jerry
When creating an object directly from an interface you must follow the Key-Value rule. This means that all members in this object are written according to the Key-Value rule.
// Create an object:
var enPerson1: Greeting = {
    name: "John",
    sayHello: function (friendName: string): string {
        return "Hello " + friendName;
    },
    sayBye: function (friendName: string): string {
        return "Good Bye";
    }
};

3. Optional Field

In TypeScript, fields of an interface can be defined as optional, which means that the class or object that implements this interface can ignore them.
interface Interface_Name  {
   optional_field_name? data_type;
   // Other fields and methods (If any)
}
In the example below, the empDept field is optional.
interface_optional_field_ex1.ts
interface IEmployee {
    empCode: number;
    empName: string;
    empDept?: string;
}
function interface_optional_field_ex1_test() {
    let tom: IEmployee = {
        empCode: 1,
        empName: "Tom"
    }
    let jerry: IEmployee = {
        empCode: 2,
        empName: "Jerry",
        empDept: "IT"
    }
    console.log(" --- tom --- ");
    console.log('tom.empName: ' + tom.empName); // Tom
    console.log('tom.empDept: ' + tom.empDept); // undefined
    console.log(" --- jerry --- ");
    console.log('jerry.empName: ' + jerry.empName); // Jerry
    console.log('jerry.empDept: ' + jerry.empDept); // IT
}
interface_optional_field_ex1_test(); // Call the function.
Output:
--- tom ---
tom.empName: Tom
tom.empDept: undefined
 --- jerry ---
jerry.empName: Jerry
jerry.empDept: IT

4. Read-only Field

TypeScript provides a way to mark a field as read only. This means that once a field is assigned a value, it cannot be changed!
In the example below, the SSN field is read-only. Once it is assigned a value, you cannot assign another value to it. The compiler will report an error if you violate that.
interface_readonly_field_ex1.ts
interface Citizen {
    name: string;
    readonly SSN: number;
}
function interface_readonly_field_ex1_test() {
    let personObj: Citizen = {
        SSN: 11111,
        name: 'Tom'
    };
    personObj.name = 'Jerry'; // OK
    personObj.SSN = 22222; // Compiler Error (!!!!!)
}  
interface_readonly_field_ex1_test(); // Call the function.

5. The interface extends from other interfaces

In TypeScript, an interface can extend from one or more interfaces according to the following syntax:
interface C extends A, B {
   // codes..
}
Example:
interface_extends_ex1.js
interface IAnimal {
    name: string;
}
interface ICat extends IAnimal {
    age: number;
    move(): void;
}
function interface_extends_ex1_test() {
    let tom = {
        name: "Tom",
        age: 3,
        move: function () {
            console.log("Moving...");
        }
    };
    console.log(`Name: ${tom.name}`);
    console.log(`Age: ${tom.age}`);
    tom.move();
}
interface_extends_ex1_test(); // Call the function.
Output:
Name: Tom
Age: 3
Moving...

6. Implement interfaces

Similar to Java and C#. Interface in TypeScript can be implemented by a class. Basically, a class can implement one or more interfaces, which must comply with the structure defined by all those interfaces.

7. Function-Type Interface

TypeScript has the same concept of Functional Interface as in Java. We temporarily call it Function-Type Interface - An interface has only one method, and this method has no name, which only includes parameters and return type. Function-Type Interface is used as a function, sometimes it also has optional fields.
Syntax to define Functional Interface:
interface Interface_Name  {
     (param_name_1 data_type_1, param_name_n data_type_n): return_data_type;
}
Function-Type Interface is a special interface, which is used as a function, not a data type.
It doesn't make much sense to write an interface that extends from a Function-Type Interface.
Or writing a class that implements a Function-Type Interface is not possible.
Example:
interface IFormatter {
    (text:string) : number;
}
The Functional interface is used as a function. See the following example:
functional_interface_ex1.js
interface IFormatter {
    (text:string) : number;
}
function functional_interface_ex1_test()  {
   var intFormatter: IFormatter = function(text:string): number {
       return parseInt(text);
   }
   var floatFormatter: IFormatter = function(text:string): number {
       return parseFloat(text);
   }
   var text:string = "2001.55";

   var value1 = intFormatter(text); // Use as a function
   console.log(value1);  // 2001
   var value2 = floatFormatter(text); // Use as a function
   console.log(value2);  // 2001.55
} 
functional_interface_ex1_test(); // Call the function.
Output:
2001
2001.55
The Function-Type Interface can include optional fields. For example:
functional_interface_ex2.ts
interface IFormatter {
    (text:string) : number;
    description? : string;
}
function functional_interface_ex2_test()  {
   var intFormatter: IFormatter = function(text:string): number {
       return parseInt(text);
   }  
   intFormatter.description = "Format a string to integer";
  
   var text: string = "2001.55";
   var result = intFormatter(text); // Use as a function
   console.log(intFormatter.description);  // Format a string to integer
   console.log(result);  // 2001  
}
functional_interface_ex2_test(); // Call the function.
Output:
Format a string to integer
2001

8. Array-Type Interface

TypeScript provides an interface type to simulate an array, which is called Array-Type Interface.
Syntax:
interface Interface_Name  {
    [index_name_1: index_data_type_1] : value_data_type;
    [index_name_n: index_data_type_n] : value_data_type;
    // Other properties and methods (If any) ...
}
Note: index_data_type_1,..., index_data_type_n must be different, otherwise you will get an error message:
Duplicate index signature for type 'xxx'
Example:
interface_array_ex1.ts
interface IEmployeeSalary {
    [emp_name:string]:number; // emp_name --> salary
}
function interface_array_ex1_test()  {
    var salaryMap : IEmployeeSalary = {};

    salaryMap["Tom"] = 2000;  
    salaryMap["Jerry"] = 1500;  
    salaryMap["Donald"] = 3000;  

    console.log(salaryMap["Jerry"]); // 1500  
}
interface_array_ex1_test(); // Call the function.
Example: An Array-Type Interface with index_data_type is number.
interface_array_ex2.ts
interface IFootballerArray {
    [index:number]:string;
}
function interface_array_ex2_test()  {
    var footballerArray : IFootballerArray = ["Ronaldo", "Messi", "Pele"];

    console.log(footballerArray[0]); // Ronaldo
    console.log(footballerArray[1]); // Messi

    footballerArray[0.5] = "<Funny>";
    console.log(footballerArray[0.5]); // <Funny>
}
interface_array_ex2_test(); // Call the function.
Output:
Ronaldo
Messi
<Funny>
Example: An Array-Type Interface with fields and methods:
interface_array_ex2b.ts
interface IFootballPlayerArray {
    description: string;
    someMethod(): string;
    [index: number]: string;
}
function interface_array_ex2b_test() {
    var footballerArray: IFootballPlayerArray = {
        description: "Famous Football Players",
        someMethod: function (): string {
            return "Something";
        }
    }
    footballerArray[0] = "Ronaldo";
    footballerArray[1] = "Messi";
    footballerArray[2] = "Pele";
    footballerArray[0.5] = "<Funny>";

    console.log(footballerArray.description); // Famous Football Players
    console.log(footballerArray.someMethod()); // Something
    console.log(" --- "); //  ---
    console.log(footballerArray[0]); // Ronaldo
    console.log(footballerArray[1]); // Messi
    console.log(footballerArray[0.5]); // <Funny>
}
interface_array_ex2b_test(); // Call the function.
Output:
Famous Football Players
Something
 ---
Ronaldo
Messi
<Funny>
Example: An Array-Type Interface with 2-dimensional indexes:
interface_array_2d_ex1.ts
interface IStaff {
    [staff_id:number] : number; // staff_id --> salary
    [staff_number:string] : number; // staff_number --> salary
}
function interface_array_2d_ex1_test()  {
    var staffArray : IStaff = {};

    staffArray[100] = 2000;  
    staffArray[101] = 1500;  
    staffArray[102] = 3000;  

    staffArray["S-100"] = 2000;  
    staffArray["S-101"] = 1500;  
    staffArray["S-102"] = 3000;  

    console.log(staffArray[100]); // 2000  
    console.log(staffArray[102]); // 3000  
    console.log(" --- ");  
    console.log(staffArray["S-100"]); // 2000  
    console.log(staffArray["S-102"]); // 3000  
}
interface_array_2d_ex1_test(); // Call the function.
Output:
2000
3000
 ---
2000
3000