- Sinifdə sahələri tipləri ilə elan etmək
public,private,protectedvəreadonlymodifikatorlarını düzgün seçməkimplementsilə sinfin interfeysə uyğunluğunu yoxlamaq və parametr xassələrindən istifadə etməkenumilə literal tiplərin birləşməsi arasında seçim etmək
JavaScript kursunda BankAccount sinfini yazmışdıq. Orada bir zəif yer vardı: istənilən kod account.balance = 1000000 yaza bilərdi və buna heç nə mane olmurdu. TypeScript siniflərə üç şey əlavə edir: sahələrin tipləri, kimin nəyə müraciət edə biləcəyini təyin edən giriş modifikatorları və sinfin interfeysə uyğunluğunun yoxlanması. Dərsin sonunda isə sabit qiymətlər dəsti üçün iki yanaşmanı — enum-u və literal tiplərin birləşməsini — müqayisə edəcəyik.
Tipli sahələr
JavaScript-də sahəni konstruktorda this.owner = owner yazmaqla yaratmaq kifayət idi. TypeScript-də hər sahə sinfin gövdəsində tipi ilə birlikdə elan olunmalıdır. Elan etməsən, kompilyator error TS2339: Property 'owner' does not exist on type 'BankAccount'. xətasını verəcək. Metodların parametrləri və qaytardıqları qiymətlər adi funksiyalardakı kimi tiplənir.
class BankAccount {
owner: string;
balance: number;
constructor(owner: string, balance = 0) {
this.owner = owner;
this.balance = balance;
}
deposit(amount: number): void {
this.balance += amount;
}
}
const account = new BankAccount('Aysel', 100);
account.deposit(50);
console.log(`${account.owner}: ${account.balance} AZN`);
account.balance = 1000000;
console.log(`${account.owner}: ${account.balance} AZN`);Aysel: 150 AZN Aysel: 1000000 AZN
Giriş modifikatorları
| Modifikator | Kim müraciət edə bilər |
|---|---|
public | hamı; heç nə yazılmayanda susmaya görə belədir |
private | yalnız həmin sinfin içindəki kod |
protected | sinfin özü və ondan törəyən siniflər |
readonly | hamı oxuya bilər, qiyməti yalnız elanda və ya konstruktorda vermək olar |
class BankAccount {
readonly owner: string;
private balance: number;
constructor(owner: string, balance = 0) {
this.owner = owner;
this.balance = balance;
}
}
const account = new BankAccount('Aysel', 100);
account.balance = 1000000;
account.owner = 'Murad';account.ts:12:9 - error TS2341: Property 'balance' is private and only accessible within class 'BankAccount'.
12 account.balance = 1000000;
~~~~~~~
account.ts:13:9 - error TS2540: Cannot assign to 'owner' because it is a read-only property.
13 account.owner = 'Murad';
~~~~~protected sahə kənardan gizlidir, amma törəmə siniflər onu görür. Əmanət hesabı faizi hesablamaq üçün valideynin balansına müraciət etməlidir:
class Account {
protected balance = 0;
deposit(amount: number): void {
this.balance += amount;
}
}
class SavingsAccount extends Account {
addInterest(rate: number): number {
this.balance += (this.balance * rate) / 100;
return this.balance;
}
}
const leyla = new SavingsAccount();
leyla.deposit(1000);
console.log(leyla.addInterest(5));
console.log(leyla.balance);savings.ts:19:19 - error TS2445: Property 'balance' is protected and only accessible within class 'Account' and its subclasses.
19 console.log(leyla.balance);
~~~~~~~SavingsAccount daxilində this.balance icazəlidir, kənarda leyla.balance isə yox.implements və parametr xassələri
class Square implements Shape yazılışı kompilyatordan xahişdir: «Yoxla ki, bu sinifdə Shape interfeysinin tələb etdiyi hər şey var». Metodu unutsan, səhv interfeysdən istifadə olunan yerdə yox, elə sinfin özündə göstəriləcək:
interface Shape {
name: string;
area(): number;
}
class Circle implements Shape {
name = 'circle';
radius: number;
constructor(radius: number) {
this.radius = radius;
}
area(): number {
return Math.PI * this.radius ** 2;
}
}
class Square implements Shape {
name = 'square';
side: number;
constructor(side: number) {
this.side = side;
}
}shapes.ts:19:7 - error TS2420: Class 'Square' incorrectly implements interface 'Shape'.
Property 'area' is missing in type 'Square' but required in type 'Shape'.
19 class Square implements Shape {
~~~~~~class Circle {
constructor(private radius: number, public label = 'circle') {}
area(): number {
return Math.PI * this.radius ** 2;
}
}
const c = new Circle(2);
console.log(c.label, c.area().toFixed(2));circle 12.57
radius və label — bir sətirdə elan olunub və doldurulub.enum, yoxsa literal tiplər?
Enum (sadalama) bir-biri ilə əlaqəli adlı sabitlər dəstidir. Qiymət verilməsə, üzvlər 0-dan başlayaraq nömrələnir; sətir qiymətləri də vermək olar. Enum TypeScript-in tiplərdən əlavə JavaScript kodu yaradan nadir imkanlarındandır: kompilyator ondan real obyekt düzəldir.
enum Direction {
Up,
Down,
Left,
Right,
}
enum Status {
Active = 'ACTIVE',
Blocked = 'BLOCKED',
}
console.log(Direction.Left);
console.log(Direction[2]);
console.log(Status.Blocked);2 Left BLOCKED
Direction[2] adı qaytarır.var Status;
(function (Status) {
Status["Active"] = "ACTIVE";
Status["Blocked"] = "BLOCKED";
})(Status || (Status = {}));tsc enum Status-dan bu JavaScript kodunu yaradır — enum silinmir, proqramda qalır.Çox vaxt eyni işi literal tiplərin birləşməsi görür. O, tamamilə silinir, qiymətlər adi sətirlərdir, səhvləri isə kompilyator eynilə tutur:
type Status = 'active' | 'blocked' | 'deleted';
function label(status: Status): string {
switch (status) {
case 'active':
return 'Active user';
case 'blocked':
return 'Blocked';
case 'deleted':
return 'Deleted';
}
}
console.log(label('blocked'));
label('banned');status.ts:15:7 - error TS2345: Argument of type '"banned"' is not assignable to parameter of type 'Status'.
15 label('banned');
~~~~~~~~| Cəhət | enum | Literal tiplərin birləşməsi |
|---|---|---|
| İcra zamanı | real obyekt yaradılır | tamamilə silinir |
| Qiymətin yazılışı | Status.Blocked | 'blocked' |
node file.ts (tiplərin silinməsi) | dəstəklənmir | işləyir |
| Bütün qiymətləri siyahı kimi almaq | Object.values(Status) ilə mümkündür | tipdən birbaşa mümkün deyil |
Əsas fikirlər
- TypeScript-də sinfin hər sahəsi gövdədə tipi ilə birlikdə elan olunur.
public— hamı,private— yalnız sinif,protected— sinif və törəmələri,readonly— yalnız oxumaq üçün.privateyalnız kompilyasiya zamanı yoxlanılır; icra zamanı gizlilik üçün#sahələri var.implementssinfin interfeysə uyğunluğunu yoxlayır;constructor(private x: T)sahəni qısa yolla elan edir.- Enum real JavaScript obyekti yaradır; literal tiplərin birləşməsi isə silinir və əksər hallarda daha yaxşı seçimdir.
Özünü yoxla
10 sual. Hər düzgün cavab XP qazandırır.