Mundarija (34)
- Bu darsda
- 1. Nega bu kerak?
- 2. Overload imzolari
- 2.1 Yozuv
- 2.2 Implementatsiya imzosi yashirin
- 2.3 Argumentlar soni bo'yicha overload
- 2.4 Implementatsiya hamma overload'ga mos bo'lsin
- 2.5 Overload tur ichida: chaqiruv imzolari
- 3. Overload, union yoki generic?
- 3.1 Natija bir xil bo'lsa — union yetadi
- 3.2 Natija kirish turini "aks ettirsa" — generic
- 3.3 Qaror jadvali
- 4. this parametri
- 4.1 this ning turi qayerdan keladi?
- 4.2 this ni birinchi parametr sifatida yozish
- 4.3 TypeScript ushlamaydigan tuzoq: ajratib olingan metod
- 5. Polimorfik this: meros bilan uzilmaydigan zanjir
- 5.1 Zanjirli (fluent) API
- 5.2 : this — "qaysi klass ustida chaqirilsa, o'sha"
- 5.3 this is …: metod — tur predikati
- 6. Ko'p uchraydigan xatolar
- 6.1 Implementatsiya imzosini chaqirmoqchi bo'lish
- 6.2 Keraksiz overload
- 6.3 Implementatsiya overload'ga mos emas
- 6.4 this turisiz oddiy funksiya
- 6.5 Metodni ajratib callback qilish
- 6.6 Zanjirda ota klass turi
- 7. Mashqlar
- 1-mashq (oson): Qaysi overload tanlanadi?
- 2-mashq (o'rta): this bilan himoyalang
- 3-mashq (qiyin): Amaliy tajriba — narx formati va chek
- 8. Real ishda
- Xulosa
- Manbalar
TypeScript function overload va this turi: bir funksiya — bir nechta imzo
Qisqacha: Overload — bitta funksiyaga bir nechta imzo yozish:
find(id: number): Dish | undefinedvafind(text: string): Dish[]. Chaqiruvchi faqat shu imzolarni ko'radi, natija turi esa berilgan argumentga qarab tanlanadi.thisparametri (function label(this: Dish)) funksiya qaysi obyekt ustida chaqirilishi kerakligini yozadi,: thisnatija turi esa bola klasslarda ham uzilmaydigan zanjir beradi.
Bu darsda
- Overload imzolari va implementatsiya imzosini yozasiz, ularning qoidalarini bilasiz.
No overload matches this callkabi xabarlarni o'qiysiz.- Overload, union parametr va generic orasida tanlay olasiz.
thisparametri bilan "kontekst yo'qolishi" xatosinitscga ushlatasiz.- Polimorfik
thisnatija turi bilan meros olinadigan zanjir (fluent) API yozasiz.
Oldin bilishingiz kerak: Generics ilg'or amaliyoti, Funksiyalarni tiplash, Narrowing, this: to'rt qoida va arrow istisnosi, Klasslar TypeScript'da.
1. Nega bu kerak?
O'tgan darsda generic'larning nozik joylarini ko'rdik. Endi boshqa holat: funksiya argument turiga qarab turli natija qaytaradi.
Sardor menyudan qidiruv funksiyasini yozdi. Raqam berilsa — id bo'yicha bitta taom, matn berilsa — nomida shu matn bor taomlar ro'yxati:
type Dish = { id: number; name: string; price: number };
const MENU: Dish[] = [{ id: 1, name: "Osh", price: 35000 }];
function find(key: number | string): Dish | undefined | Dish[] {
if (typeof key === "number") {
return MENU.find((d) => d.id === key);
}
return MENU.filter((d) => d.name.includes(key));
}
const result = find(1);
console.log(Array.isArray(result)); // falseIshlaydi, lekin natija turi — Dish | undefined | Dish[]. Sardor find(1) chaqirganda bitta taom kelishini biladi, TypeScript esa bilmaydi. Har chaqiruvdan keyin Array.isArray bilan tekshirish kerak — aks holda result.name ham, result.length ham TS2339 beradi. Bizga kerak: "son berilsa — Dish | undefined, satr berilsa — Dish[]" degan aniq bog'lanish.
2. Overload imzolari
2.1 Yozuv
type Dish = { id: number; name: string; price: number };
const MENU: Dish[] = [
{ id: 1, name: "Osh", price: 35000 },
{ id: 2, name: "Manti", price: 30000 },
{ id: 3, name: "Lag'mon", price: 28000 },
];
function find(id: number): Dish | undefined;
function find(text: string): Dish[];
function find(key: number | string): Dish | undefined | Dish[] {
if (typeof key === "number") {
return MENU.find((d) => d.id === key);
}
return MENU.filter((d) => d.name.includes(key));
}
const one = find(2);
const many = find("a");
console.log(one?.name, many.length); // Manti 2Uch qism:
- Overload imzolari (overload signatures) — tanasiz ikki qator. Ular chaqiruvchi uchun "menyu":
find(id: number)yokifind(text: string). - Implementatsiya imzosi (implementation signature) — tanali oxirgi e'lon. U hamma overload'larni qamrab olishi kerak (
number | string), lekin tashqaridan ko'rinmaydi. - Tanada — oddiy toraytirish (
typeof key === "number").
Natija: one — Dish | undefined, many — Dish[]. Hover ham shuni ko'rsatadi va muharrir find( yozganda ikki variantni "1/2", "2/2" deb taklif qiladi.
Overload (function overloading — "funksiyani qayta yuklash") — bir nomga bir nechta chaqiruv shakli. Kundalik o'xshatish: kassadagi bitta "To'lov" tugmasi — naqd bersangiz qaytim chiqaradi, karta bersangiz chek. Tugma bitta, natija esa nima berganingizga bog'liq.
2.2 Implementatsiya imzosi yashirin
Implementatsiya number | string qabul qiladi. Lekin uni to'g'ridan-to'g'ri chaqirib bo'lmaydi:
type Dish = { id: number; name: string };
function find(id: number): Dish | undefined;
function find(text: string): Dish[];
function find(key: number | string): Dish | undefined | Dish[] {
return typeof key === "number" ? undefined : [];
}
const key: number | string = Math.random() > 0.5 ? 1 : "osh";
find(key);
find(true);Kompilyator:
TS2769: No overload matches this call.
The last overload gave the following error.
Argument of type 'string | number' is not assignable to parameter of type 'string'.
Type 'number' is not assignable to type 'string'.
TS2769: No overload matches this call.
The last overload gave the following error.
Argument of type 'boolean' is not assignable to parameter of type 'string'.Tarjimasi: "Bu chaqiruvga birorta ham overload mos kelmadi. Oxirgi overload shunday xato berdi: …". Birinchi chaqiruv qiziq: key — "son yoki satr", lekin har bir overload faqat bittasini qabul qiladi. Implementatsiyadagi number | string chaqiruvchiga ko'rinmaydi. TypeScript overload'larni tartib bilan sinaydi va oxirgisining xatosini ko'rsatadi. find(key) uchun bu shunday o'tdi:
| Qadam | Nima bo'ldi? | Natija |
|---|---|---|
| 1 | 1-imzo find(id: number) sinaldi |
string | number ≠ number — mos emas |
| 2 | 2-imzo find(text: string) sinaldi |
string | number ≠ string — mos emas |
| 3 | Imzolar tugadi, implementatsiya hisobga olinmaydi | TS2769, oxirgi (2-) imzoning xatosi bilan |
Bu xabar DOM bilan ishlaganda ko'p uchraydi — masalan, addEventListener ning bir nechta overload'i bor. vazifalar dagi trusted-types.d.ts ham register() ga overload qo'shgan edi (Kengaytirish va declaration merging).
2.3 Argumentlar soni bo'yicha overload
Overload'lar argumentlar sonida ham farq qilishi mumkin:
function makeTime(minutes: number): string;
function makeTime(h: number, m: number, s: number): string;
function makeTime(a: number, b?: number, c?: number): string {
return `${a}:${b ?? 0}:${c ?? 0}`;
}
makeTime(10, 30);Kompilyator:
TS2575: No overload expects 2 arguments, but overloads do exist that expect either 1 or 3 arguments.Tarjimasi: "2 argument kutadigan overload yo'q, lekin 1 yoki 3 argumentli overload'lar bor". Implementatsiyada b va c ixtiyoriy — u 2 argumentni bemalol qabul qilardi. Lekin chaqiruvchi faqat overload'larni ko'radi.
2.4 Implementatsiya hamma overload'ga mos bo'lsin
function double(x: string): string;
function double(x: number): number {
return x * 2;
}Kompilyator:
TS2394: This overload signature is not compatible with its implementation signature.Tarjimasi: "Bu overload imzosi implementatsiya imzosiga mos emas". Implementatsiya faqat number qabul qiladi — string li overload uchun joy yo'q. Implementatsiya imzosi hamma overload parametrlarini (union) va hamma natijalarni qamrab olishi kerak.
2.5 Overload tur ichida: chaqiruv imzolari
Overload faqat function e'lonida emas — tur ham bir nechta chaqiruv shaklini tasvirlay oladi. Buning uchun obyekt turi ichida nomsiz imzolar yoziladi:
type Dish = { id: number; name: string };
type Finder = {
(id: number): Dish | undefined;
(text: string): Dish[];
};
const menu: Dish[] = [{ id: 1, name: "Osh" }];
function findImpl(id: number): Dish | undefined;
function findImpl(text: string): Dish[];
function findImpl(key: number | string): Dish | undefined | Dish[] {
if (typeof key === "number") return menu.find((d) => d.id === key);
return menu.filter((d) => d.name.includes(key));
}
const find: Finder = findImpl;
console.log(find(1)?.name, find("O").length); // Osh 1(id: number): Dish | undefined; — chaqiruv imzosi (call signature): "bu turdagi qiymatni shunday chaqirish mumkin". Bunday tur funksiyani parametr sifatida qabul qilishda kerak: masalan, qidiruv funksiyasini boshqa modulga uzatganda. Kutubxonalarning .d.ts fayllarida overload'lar ko'pincha aynan shu shaklda yoziladi (Declaration fayllari darsida). interface ichida ham xuddi shunday yoziladi, klass metodlari uchun esa function dagi kabi — metod nomi bilan bir necha qator.
Tekshirib ko'ring: Overload'li
finduchunfind(2)vafind("2")natija turlari qanday?
Javob
find(2) — Dish | undefined (birinchi overload), find("2") — Dish[] (ikkinchi overload): "2" — satr, u nomlar ichidan qidiriladi. Tur argumentning turiga qarab tanlanadi, qiymatiga emas.
3. Overload, union yoki generic?
3.1 Natija bir xil bo'lsa — union yetadi
Overload — og'ir vosita. Ko'pincha keraksiz:
// ❌ ikki overload, natija bir xil
// function len(s: string): number;
// function len(arr: readonly unknown[]): number;
// ✅ union parametr
function len(value: string | readonly unknown[]): number {
return value.length;
}
console.log(len("Osh"), len([1, 2, 3])); // 3 3Overload versiyasi bilan len(Math.random() > 0.5 ? "a" : [1]) — TS2769 berardi (har overload faqat bittasini oladi). Union versiyasi esa uni qabul qiladi. TypeScript hujjatlaridagi qoida: iloji bo'lsa, overload o'rniga union parametr yozing.
3.2 Natija kirish turini "aks ettirsa" — generic
Funksiya kirgan turni o'zgartirmay qaytarsa (first, identity), overload emas, generic kerak. Overload bilan har tur uchun alohida qator yozishga to'g'ri kelardi.
3.3 Qaror jadvali
| Holat | Tanlov |
|---|---|
| Parametr turlari har xil, natija bir xil | union parametr |
| Natija kirish turining o'zi yoki unga bog'liq | generic |
| Har kirish turiga boshqa-boshqa, oldindan ma'lum natija | overload |
| Argumentlar soni har xil va ma'nosi boshqacha | overload yoki ikki alohida funksiya |
Oxirgi qatorda "ikki alohida funksiya" ham bor: findById(id) va searchByName(text) — ko'pincha overload'dan ham tushunarliroq. Overload asosan mavjud JavaScript API'larini tiplash uchun kerak (DOM, Node, eski kutubxonalar).
Generic va overload birga ham ishlaydi: masalan, document.createElement — har teg nomiga o'z element turi. U Generic cheklovlar va keyof darsidagi K extends keyof … naqshi bilan yozilgan: createElement("input") — HTMLInputElement. Buni TypeScript va DOM darsida ko'rasiz.
Tekshirib ko'ring:
function toText(x: number): string; function toText(x: boolean): string;— buni qanday soddalashtirish mumkin?
Javob
Bitta imzo: function toText(x: number | boolean): string. Natija ikkala holatda ham string — overload hech narsa bermaydi, aksincha number | boolean turidagi qiymatni qabul qilmay qo'yadi.
4. this parametri
4.1 this ning turi qayerdan keladi?
this: to'rt qoida darsidan bilasiz: oddiy funksiyada this qanday chaqirilganiga qarab o'zgaradi. TypeScript buni oldindan bilmaydi:
function describe() {
return this.name;
}Kompilyator:
TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.Tarjimasi: "this yashirincha any turini oldi, chunki unga tur yozilmagan". Bu strict ichidagi noImplicitThis bayrog'ining ishi.
4.2 this ni birinchi parametr sifatida yozish
TypeScript'da this ning turini maxsus "soxta" birinchi parametr bilan yoziladi:
type Dish = { name: string; price: number };
function label(this: Dish): string {
return `${this.name}: ${this.price} so'm`;
}
const osh: Dish = { name: "Osh", price: 35000 };
console.log(label.call(osh)); // Osh: 35000 so'm
const manti = { name: "Manti", price: 30000, label };
console.log(manti.label()); // Manti: 30000 so'mthis: Dish — parametr emas: chaqiruvda argument sifatida berilmaydi va JavaScript'da butunlay o'chadi. U faqat "bu funksiya Dish ustida chaqirilishi kerak" degan talab. label.call(osh) va manti.label() — ikkalasida ham this Dish ga mos.
Talab bajarilmasa:
type Dish = { name: string; price: number };
function label(this: Dish): string {
return this.name;
}
label();Kompilyator:
TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'Dish'.Tarjimasi: "void turidagi this konteksti metodning Dish turidagi this iga mos emas". Oddiy label() chaqiruvida this — hech narsa (void). JavaScript'da bu TypeError bo'lardi, TypeScript esa uni yozish paytida ushladi.
4.3 TypeScript ushlamaydigan tuzoq: ajratib olingan metod
Klass metodlarida this ning turi avtomatik — klassning o'zi. Lekin metodni obyektdan ajratib olsangiz:
class Order {
items: string[] = [];
add(dish: string): void {
this.items.push(dish);
}
}
const order = new Order();
const add = order.add;
add("Osh");tsc — xatosiz. Node esa:
TypeError: Cannot read properties of undefined (reading 'items')const add = order.add — funksiya obyektdan ajraldi. add("Osh") da this — undefined (modul doim strict rejimda). TypeScript klass metodlarida this ni "doim to'g'ri" deb hisoblaydi va ajratib olishni tekshirmaydi. Bu this yo'qolishi va uni tiklash darsidagi xatoning aynan o'zi — TypeScript ham uni o'zi ko'rmaydi. Bu tugma bosilganda chaqiriladigan callback'larda (button.addEventListener("click", order.add)) eng ko'p uchraydi.
Uch himoya:
- Metodga
thisparametrini yozing:add(this: Order, dish: string)— endiadd("Osh")TS2684beradi. - Callback'ni o'rang:
addEventListener("click", () => order.add("Osh")). - Klass maydonini arrow funksiya qiling:
add = (dish: string): void => { … }— arrowthisni yaratilgan joydan oladi. Narxi — har nusxada alohida funksiya.
vazifalar da ESLint'ning typescript-eslint qoidalari bor; ulardan biri — unbound-method — aynan shunday ajratib olishni ko'rsatadi (turli tekshiruvli qoidalar — Async kod va xatolarni tiplash qadamida).
5. Polimorfik this: meros bilan uzilmaydigan zanjir
5.1 Zanjirli (fluent) API
Har metod this ni qaytarsa, chaqiruvlarni zanjir qilib yozish mumkin: builder.add(…).add(…).build(). Chek yasovchi klass:
class OrderBuilder {
protected items: string[] = [];
add(dish: string): OrderBuilder {
this.items.push(dish);
return this;
}
}
class VipOrderBuilder extends OrderBuilder {
#note = "";
note(text: string): OrderBuilder {
this.#note = text;
return this;
}
}
new VipOrderBuilder().add("Osh").note("Achchiqsiz");Kompilyator:
TS2339: Property 'note' does not exist on type 'OrderBuilder'.Tarjimasi: "OrderBuilder turida note xususiyati yo'q". add OrderBuilder qaytaradi deb yozilgan. VipOrderBuilder ustida chaqirilgan bo'lsa ham, natija turi — ota klass. Unda note yo'q — zanjir uzildi.
5.2 : this — "qaysi klass ustida chaqirilsa, o'sha"
Natija turini this deb yozamiz:
class OrderBuilder {
protected items: string[] = [];
add(dish: string): this {
this.items.push(dish);
return this;
}
build(): string {
return this.items.join(", ");
}
}
class VipOrderBuilder extends OrderBuilder {
note(text: string): this {
this.items.push(`(${text})`);
return this;
}
}
const text = new VipOrderBuilder()
.add("Osh")
.note("achchiqsiz")
.add("Ko'k choy")
.build();
console.log(text); // Osh, (achchiqsiz), Ko'k choy: this — polimorfik this turi: "metod qaysi klassning nusxasi ustida chaqirilgan bo'lsa, o'sha tur". VipOrderBuilder ustida add endi VipOrderBuilder qaytaradi — note ham, build ham zanjirda qoladi.
Chizmada farq:
flowchart LR
A["new VipOrderBuilder()"] --> B[".add('Osh')"]
B -- ": OrderBuilder" --> C["note yo'q<br/>TS2339"]
B -- ": this" --> D[".note(…)"]
D --> E[".build()"]: OrderBuilder yo'lida zanjir birinchi bo'g'indan keyin "ota klassga tushib" qoldi. : this yo'lida tur har qadamda aniq qoldi.
5.3 this is …: metod — tur predikati
this tur predikatida ham ishlaydi. Custom type guard darsida x is Dish ko'rinishini o'rgangansiz — metodda x o'rnida obyektning o'zi:
class Table {
readonly no: number;
guest: string | null = null;
constructor(no: number) {
this.no = no;
}
isBusy(): this is { guest: string } {
return this.guest !== null;
}
}
const table = new Table(7);
table.guest = "Dilshod aka";
if (table.isBusy()) {
console.log(table.guest.toUpperCase()); // DILSHOD AKA
}isBusy(): this is { guest: string } — "true qaytsa, bu obyektda guest — satr". if ichida table.guest string | null dan string ga torayadi, ?. yoki ! kerak emas. Tekshiruv mantiqi klass ichida bir marta yoziladi, chaqiruvchi esa faqat metod nomini o'qiydi.
Tekshirib ko'ring:
OrderBuilderdaadd(): this, lekinbuild(): string.new VipOrderBuilder().build().note("x")— xato bormi?
Javob
Bor: build() satr qaytaradi, satrda note yo'q — TS2339: Property 'note' does not exist on type 'string'. Zanjir this qaytaradigan metodlar ustida davom etadi, natija beradigan build esa zanjirni tugatadi.
6. Ko'p uchraydigan xatolar
6.1 Implementatsiya imzosini chaqirmoqchi bo'lish
number | string turidagi qiymat bilan overload'li funksiya — TS2769. Tuzatish: union qabul qiladigan overload qo'shing yoki overload o'rniga union parametr.
6.2 Keraksiz overload
Natija bir xil bo'lsa, overload faqat cheklaydi. Tuzatish: union parametr.
6.3 Implementatsiya overload'ga mos emas
TS2394. Tuzatish: implementatsiya parametrlari hamma overload'larni qamrab olsin (union).
6.4 this turisiz oddiy funksiya
TS2683. Tuzatish: function f(this: Dish) yoki arrow/metodga aylantiring.
6.5 Metodni ajratib callback qilish
const add = order.add — tsc jim, Node'da TypeError. Tuzatish: o'rash (() => order.add(x)), this parametri yoki arrow maydon.
6.6 Zanjirda ota klass turi
add(): OrderBuilder — bola klass metodlari zanjirdan tushib qoladi. Tuzatish: add(): this.
7. Mashqlar
1-mashq (oson): Qaysi overload tanlanadi?
function size(value: string): number;
function size(value: readonly number[]): number[];
function size(value: string | readonly number[]): number | number[] {
return typeof value === "string" ? value.length : [value.length];
}
const a = size("Manti");
const b = size([1, 2]);
console.log(a, b); // 5 [ 2 ]a ning turi: [:number]. b ning turi: [:number[]]. size(Math.random() > 0.5 ? "a" : [1]) qaysi xato kodini beradi: .
Yechim
a—number: birinchi overload (satr).b—number[]: ikkinchi overload (sonlar massivi).TS2769: argument —string | number[], har overload esa faqat bittasini qabul qiladi.
2-mashq (o'rta): this bilan himoyalang
Bu klass tugma callback'ida ishlatilganda yiqiladi. tsc buni yozish paytida ushlashi uchun pay metodiga this parametrini qo'shing, keyin noto'g'ri qatorni to'g'rilang.
class Bill {
total = 63000;
pay(cash: number): number {
return cash - this.total;
}
}
const bill = new Bill();
const pay = bill.pay;
console.log(pay(100000));tsc bu kodni xatosiz o'tkazadi, Node esa ishga tushirganda yiqiladi:
TypeError: Cannot read properties of undefined (reading 'total')Yechim
this parametri qo'shilgach, pay(100000) TS2684 beradi. To'g'rilangan kod:
class Bill {
total = 63000;
pay(this: Bill, cash: number): number {
return cash - this.total;
}
}
const bill = new Bill();
const pay = (cash: number): number => bill.pay(cash);
console.log(pay(100000)); // 37000this: Bill— chaqiruvda argument emas:bill.pay(cash)avvalgidek bitta argument oladi.- Ajratib olish o'rniga arrow funksiya bilan o'radik —
bill.pay(...)chaqiruvidathisdoimbill. - Qaytim: 100 000 − 63 000 = 37 000 so'm.
3-mashq (qiyin): Amaliy tajriba — narx formati va chek
Mashq kurs/mashqlar/15/ papkasida. 24-overload/receipt.ts:
formatPrice— ikki overload: son →"35 000 so'm"(satr), sonlar ro'yxati → satrlar ro'yxati. Ishora:new Intl.NumberFormat("ru-RU").format(35000)— minglik ajratgich bilan (Intl.NumberFormat).ReceiptBuilder—add(dish, price)(qator qo'shadi),build()(qatorlarni\nbilan birlashtiradi).TableReceiptBuilder extends ReceiptBuilder—table(no): chek boshiga"Stol 7"qo'shadi. Zanjiradd(…).table(…).add(…)bola klassda ham ishlasin.
Avval add natija turini ReceiptBuilder deb yozing va testdagi zanjirni tsc bilan tekshiring.
Yechim
add(): ReceiptBuilder bilan tsc 7.0.2:
24-overload/receipt.test.ts(16,6): error TS2339: Property 'table' does not exist on type 'ReceiptBuilder'.«: this» bo'limidagi holat: add dan keyin tur ota klassga tushdi.
// 24-overload/receipt.ts — narx formati va chek yasovchi
const fmt = new Intl.NumberFormat("ru-RU");
// Bitta narx → satr, narxlar ro'yxati → satrlar ro'yxati
export function formatPrice(amount: number): string;
export function formatPrice(amounts: readonly number[]): string[];
export function formatPrice(
value: number | readonly number[],
): string | string[] {
if (typeof value === "number") {
return `${fmt.format(value)} so'm`;
}
return value.map((v) => `${fmt.format(v)} so'm`);
}
export class ReceiptBuilder {
protected lines: string[] = [];
// this — bola klassda ham zanjir uzilmaydi
add(dish: string, price: number): this {
this.lines.push(`${dish}: ${formatPrice(price)}`);
return this;
}
build(): string {
return this.lines.join("\n");
}
}
export class TableReceiptBuilder extends ReceiptBuilder {
table(no: number): this {
this.lines.unshift(`Stol ${no}`);
return this;
}
}// 24-overload/receipt.test.ts
import { test } from "node:test";
import assert from "node:assert/strict";
import { formatPrice, TableReceiptBuilder } from "./receipt.ts";
test("formatPrice: son va ro'yxat", () => {
const one: string = formatPrice(35000);
const many: string[] = formatPrice([5000, 28000]);
assert.equal(one.replace(/\s/g, " "), "35 000 so'm");
assert.equal(many.length, 2);
});
test("TableReceiptBuilder: zanjir bola klassda ham", () => {
const text = new TableReceiptBuilder()
.add("Osh", 35000)
.table(7)
.add("Ko'k choy", 5000)
.build();
assert.equal(text.split("\n")[0], "Stol 7");
assert.equal(text.split("\n").length, 3);
});typeof value === "number"bilan toraytirdik.Array.isArray(value)bilan esaelseshoxidavaluenumber | readonly number[]bo'lib qolardi: bu tekshiruvreadonlymassivni chiqarib tashlamaydi (TypeScript'ning ma'lum cheklovi, tsc 7.0.2 da tekshirildi). Shuning uchuntypeofqulayroq.one: stringvamany: string[]— test overload'larni ham tekshiradi: noto'g'ri overload tanlansa,tscshu qatorlarni to'xtatadi..replace(/\s/g, " ")—ru-RUformati minglikni uzilmas bo'sh joy bilan ajratadi (Tur annotatsiyasi darsidagiformatPricekabi). Taqqoslashdan oldin oddiy probelga almashtirdik.protected lines— bola klass (table) ichida ochiq, tashqarida yopiq (Klasslar TypeScript'da).
npx tsc --pretty false — chiqishsiz. node --test 24-overload/receipt.test.ts bizda (Node 24.21.0) shunday chiqdi:
✔ formatPrice: son va ro'yxat (2.3494ms)
✔ TableReceiptBuilder: zanjir bola klassda ham (0.452ms)
ℹ tests 2
ℹ suites 0
ℹ pass 2
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 302.926XATOLAR.md ga qo'shing: TS2769, TS2575, TS2394, TS2683, TS2684. Keyin kurs/mashqlar papkasidan:
git add 15/24-overload 15/XATOLAR.md
git commit -m "15/24: receipt.ts — overload va polimorfik this"8. Real ishda
- Kutubxona turlari overload'larga to'la:
addEventListener,createElement,JSON.stringify, Node'ningfs.readFile(kodlash berilsa —string, berilmasa —Buffer).tscxabarida "No overload matches this call" ko'rsangiz — hover'da overload ro'yxatini oching va qaysi biriga yaqin ekaningizni toping. - Builder va query API'lari —
: thiszanjirlari: so'rov yasovchilar (query.where(…).orderBy(…).limit(…)), test kutubxonalaridagiexpect(…).not.toBe(…)kabi. thisva callback'lar — React klass komponentlari davridan qolgan eng mashhur xato. Bugun arrow funksiyalar uni kamaytirgan, lekin eski kodda uchraydi.- Intervyu: "Overload va union farqi?", "Implementatsiya imzosi nega ko'rinmaydi?", "Polimorfik
thisnima?" — middle darajadagi savollar.
Xulosa
- Overload — tanasiz bir nechta imzo va bitta implementatsiya. Chaqiruvchi faqat imzolarni ko'radi; implementatsiya ularning hammasini qamrab olishi kerak (
TS2394). - Mos overload topilmasa —
TS2769(turi) yokiTS2575(argumentlar soni). - Natija bir xil bo'lsa — union, kirish turini aks ettirsa — generic, har turga boshqa natija bo'lsa — overload.
this: Tur— soxta birinchi parametr: JavaScript'da o'chadi,tscda esa noto'g'ri chaqiruvni ushlaydi (TS2684). Klass metodini ajratib olishnitsco'zi ko'rmaydi.: thisnatija turi — meros olinganda ham uzilmaydigan zanjir.
Keyingi dars: keyof, typeof va indexed access — mavjud qiymat va turlardan yangi turlarni chiqarib olish: typeof MENU, Dish["price"], (typeof SIZES)[number].
Manbalar
- TypeScript Handbook: "More on Functions" (Function Overloads, Writing Good Overloads, Declaring
thisin a Function) — typescriptlang.org/docs/handbook/2/functions.html#function-overloads - TypeScript Handbook: "Classes" (
thisTypes,thisparameters, Arrow Functions) — typescriptlang.org/docs/handbook/2/classes.html#this-types - TSConfig:
noImplicitThis— typescriptlang.org/tsconfig#noImplicitThis
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!