TypeScript – Rozhraní

Rozhraní je struktura, která definuje smlouvu ve vaší aplikaci. Definuje syntaxi, kterou se mají třídy řídit. Třídy, které jsou odvozeny z rozhraní, musí dodržovat strukturu danou jejich rozhraním.

Překladač jazyka TypeScript nepřevádí rozhraní do jazyka JavaScript. Pro kontrolu typů používá rozhraní. Tomu se také říká „kachní typování“ nebo „strukturální podtypování“.

Rozhraní se definuje pomocí klíčového slova interface a může obsahovat deklarace vlastností a metod pomocí funkce nebo funkce se šipkou.

Příklad: Rozhraní

Kopírovat

interface IEmployee { empCode: number; empName: string; getSalary: (number) => number; // arrow function getManagerName(number): string; }

Ve výše uvedeném příkladu obsahuje rozhraní IEmployee dvě vlastnosti empCode a empName. Dále obsahuje deklaraci metody getSalaray využívající funkci arrow, která obsahuje jeden číselný parametr a číselný návratový typ. Metoda getManagerName je deklarována pomocí normální funkce. To znamená, že každý objekt typu IEmployee musí definovat tyto dvě vlastnosti a dvě metody.

Rozhraní jako typ

Rozhraní v jazyce TypeScript lze použít k definici typu a také k jeho implementaci ve třídě.

Následující rozhraní IEmployee definuje typ proměnné.

Příklad: Rozhraní jako typ

Kopie

interface KeyPair { key: number; value: string;}let kv1: KeyPair = { key:1, value:"Steve" }; // OKlet kv2: KeyPair = { key:1, val:"Steve" }; // Compiler Error: 'val' doesn't exist in type 'KeyPair'let kv3: KeyPair = { key:1, value:100 }; // Compiler Error: 

Ve výše uvedeném příkladu rozhraní KeyPair obsahuje dvě vlastnosti key a value. Proměnná kv1 je deklarována jako typ KeyPair. Musí tedy mít stejnou strukturu jako KeyPair. To znamená, že proměnné kv1 lze přiřadit pouze objekt s vlastnostmi key typu číslo a value typu řetězec. Překladač jazyka TypeScript zobrazí chybu, pokud dojde ke změně názvu vlastností nebo je datový typ jiný než KeyPair. Další proměnná kv2 je také deklarována jako typ KeyPair, ale přiřazená hodnota je val místo value, takže to způsobí chybu. Stejně tak kv3 přiřadí vlastnosti value číslo, takže překladač zobrazí chybu. TypeScript tedy používá rozhraní, které zajišťuje správnou strukturu objektu.

Rozhraní jako typ funkce

Rozhraní jazyka TypeScript se také používá k definování typu funkce. Tím se zajistí signatura funkce.

Příklad: Typ funkce

Kopie

interface KeyValueProcessor{ (key: number, value: string): void;};function addKeyValue(key:number, value:string):void { console.log('addKeyValue: key = ' + key + ', value = ' + value)}function updateKeyValue(key: number, value:string):void { console.log('updateKeyValue: key = '+ key + ', value = ' + value)} let kvp: KeyValueProcessor = addKeyValue;kvp(1, 'Bill'); //Output: addKeyValue: key = 1, value = Bill kvp = updateKeyValue;kvp(2, 'Steve'); //Output: updateKeyValue: key = 2, value = Steve 

Ve výše uvedeném příkladu obsahuje rozhraní KeyValueProcessor signaturu metody. Ta definuje typ funkce. Nyní můžeme definovat proměnnou typu KeyValueProcessor, která může ukazovat pouze na funkce se stejnou signaturou, jaká je definována v rozhraní KeyValueProcessor. Takže funkci addKeyValue nebo updateKeyValue přiřadíme funkci kvp. Proměnnou kvp lze tedy volat jako funkci.

Pokus o přiřazení funkce s jinou signaturou způsobí chybu.

function delete(key:number):void { console.log('Key deleted.')} let kvp: KeyValueProcessor = delete; //Compiler Error

ADVERTISEMENT

Rozhraní pro typ pole

Rozhraní může také definovat typ pole, kde můžete definovat typ indexu i hodnoty.

Příklad: Typ pole

Kopírovat

interface NumList { :number}let numArr: NumList = ;numArr;numArr;interface IStringList { :string}let strArr : IStringList;strArr = "TypeScript";strArr = "JavaScript";

Ve výše uvedeném příkladu definuje rozhraní NumList typ pole s indexem jako číslo a hodnotou jako typ číslo. Stejně tak rozhraní IStringList definuje pole typu string s indexem jako string a hodnotou jako string.

Volitelné vlastnosti

Někdy můžeme deklarovat rozhraní s nadbytečnými vlastnostmi, ale nemusíme očekávat, že všechny objekty budou definovat všechny dané vlastnosti rozhraní. Můžeme mít nepovinné vlastnosti, označené znakem „?“. V takových případech objekty rozhraní mohou, ale nemusí tyto vlastnosti definovat.

Příklad:

Kopírovat

interface IEmployee { empCode: number; empName: string; empDept?:string;}let empObj1:IEmployee = { // OK empCode:1, empName:"Steve"}let empObj2:IEmployee = { // OK empCode:1, empName:"Bill", empDept:"IT"}

V uvedeném příkladu je empDept označen ?, takže objekty IEmployee mohou, ale nemusí tuto vlastnost obsahovat.

Vlastnosti pouze pro čtení

TypeScript poskytuje možnost označit vlastnost pouze pro čtení. To znamená, že jakmile je vlastnosti přiřazena hodnota, nelze ji měnit!

Příklad: V uvedeném příkladu je vlastnost SSN určena pouze pro čtení: Kopírovat
interface Citizen { name: string; readonly SSN: number;}let personObj: Citizen = { SSN: 110555444, name: 'James Bond' }personObj.name = 'Steve Smith'; // OKpersonObj.SSN = '333666888'; // Compiler Error

V uvedeném příkladu je vlastnost SSN určena pouze pro čtení. Definujeme objekt personObj typu Citizen a přiřadíme hodnoty dvěma vlastnostem rozhraní. Dále se pokusíme změnit hodnoty přiřazené oběma vlastnostem – name a SSN. Kompilátor jazyka TypeScript zobrazí chybu, když se pokusíme změnit vlastnost SSN pouze pro čtení.

Rozšiřování rozhraní

Rozhraní mohou rozšiřovat jedno nebo více rozhraní. Díky tomu je psaní rozhraní flexibilní a opakovaně použitelné.

Příklad: Rozšíření rozhraní

Kopírovat

interface IPerson { name: string; gender: string;}interface IEmployee extends IPerson { empCode: number;}let empObj:IEmployee = { empCode:1, name:"Bill", gender:"Male"}

V uvedeném příkladu rozšiřuje rozhraní IEmployee rozhraní IPerson. Objekty IEmployee tedy musí obsahovat všechny vlastnosti a metody rozhraní IPerson, jinak překladač zobrazí chybu.

Implementace rozhraní

Podobně jako v jazycích jako Java a C# lze rozhraní v jazyce TypeScript implementovat pomocí třídy. Třída implementující rozhraní musí striktně dodržovat strukturu rozhraní.

Příklad:

Kopírovat

interface IEmployee { empCode: number; name: string; getSalary:(number)=>number;}class Employee implements IEmployee { empCode: number; name: string; constructor(code: number, name: string) { this.empCode = code; this.name = name; } getSalary(empCode:number):number { return 20000; }}let emp = new Employee(1, "Steve");

Ve výše uvedeném příkladu je rozhraní IEmployee implementováno ve třídě Employee pomocí klíčového slova implement. Implementační třída by měla striktně definovat vlastnosti a funkce se stejným názvem a datovým typem. Pokud implementační třída nedodrží strukturu, pak překladač zobrazí chybu.

Implementační třída samozřejmě může definovat další vlastnosti a metody, ale přinejmenším musí definovat všechny členy rozhraní.

V příští kapitole se dozvíme více o třídách jazyka TypeScript.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.