betacode

Интерфейсы в TypeScript

  1. Что такое интерфейс?
  2. Интерфейс - это тип данных
  3. Опциональное поле
  4. Поле только для чтения (Read-only)
  5. Интерфейс простирается от других интерфейсов
  6. Реализация интерфейсов
  7. Function-Type Interface
  8. Array-Type Interface

1. Что такое интерфейс?

В TypeScript, интерфейс - это конструкция, которая объявляет стандарты. Классы, производные (derived) от интерфейса, должны соответствовать стандартам, установленным интерфейсом.
В JavaScript нет понятия интерфейсов, поэтому компилятор TypeScript не преобразует интерфейсы в JavaScript. Интерфейс используется в качестве инструмента для проверки типов в программе.
TypeScript использует ключевое слово interface для определения интерфейса. Интерфейсы могут включать поля (field), property и методы (method).
interface Greeting {
   name: string;

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

   sayBye: (friendName: string) => string; // A arrow method
}
В приведенном выше примере Greeting - это интерфейс, который включает 1 поле (field) и 2 метода.
  • name:Поле (field) с типом данных string.
  • sayHello: обычный метод с параметром типа string и возвращает string.
  • sayBye: Метод Lambda с параметром типа string и возвращает string, (Методы Lambda также известны как методы со стрелками).

2. Интерфейс - это тип данных

Интерфейс - это тип данных, и вы можете создавать объекты напрямую. Созданные объекты должны реализовывать (implements) все поля, property и методы, объявленные в интерфейсе.
Для удобства понимания см. пример:
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
При создании объекта непосредственно из интерфейса вы должны следовать правилу Key-Value. Это означает, что все члены в этом объекте записываются в соответствии с правилом Key-Value (ключ-значение).
// 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. Опциональное поле

В TypeScript поля интерфейса могут быть определены как опциональные, это означает, что класс или объект, реализующий этот интерфейс, может их игнорировать.
interface Interface_Name  {
   optional_field_name? data_type;
   // Other fields and methods (If any)
}
В приведенном ниже примере поле empDept является опциональным.
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)

TypeScript предоставляет способ пометить поле как доступное только для чтения. Это означает, что как только полю присвоено значение, оно не может быть изменено!
В приведенном ниже примере поле SSN доступно только для чтения. Как только ему будет присвоено значение, вы не сможете присвоить ему другое значение. Компилятор сообщит об ошибке, если вы нарушите это.
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. Интерфейс простирается от других интерфейсов

В TypeScript интерфейс может расширяться (extends) от одного или нескольких интерфейсов в соответствии со следующим синтаксисом:
interface C extends A, B {
   // codes..
}
Например:
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. Реализация интерфейсов

Аналогично Java и C#. Интерфейс в TypeScript может быть реализован классом. В принципе, класс может реализовать один или несколько интерфейсов, которые должны соответствовать структуре, определенной всеми этими интерфейсами.

7. Function-Type Interface

TypeScript имеет ту же концепцию j Functional Interface, что и в Java. Мы временно называем его Function-Type Interface - Интерфейс имеет только один метод, и у этого метода нет имени, он включает только параметры и тип возвращаемого значения. Function-Type Interface используется как функция, иногда он также содержит опциональные поля.
Синтаксис для определения Functional Interface:
interface Interface_Name  {
     (param_name_1 data_type_1, param_name_n data_type_n): return_data_type;
}
Function-Type Interface - это специальный интерфейс, который используется как функция, а не как тип данных.
Нет особого смысла писать интерфейс, который расширяется за счет интерфейса Function-Type Interface.
Или невозможно написать класс, реализующий Function-Type Interface.
Например:
interface IFormatter {
    (text:string) : number;
}
Functional interface используется как функция. См. Следующий пример:
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
Function-Type Inteface может включать опциональные поля. Например:
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 предоставляет тип интерфейса для имитации массива, который называется Array-Type Interface.
Синтаксис:
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) ...
}
Примечание: index_data_type_1,..., index_data_type_n должны отличаться, в противном случае вы получите сообщение об ошибке:
Duplicate index signature for type 'xxx'
Например:
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.
Например: Array-Type Interface с типом index_data_typenumber.
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>
Например: Array-Type Interface с полями и методами:
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>
Например: Array-Type Interface с 2-мерными индексами (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