IlmHamroh
JavaScript Full-stack/15-qism. TypeScript24/47-dars18 daqiqa
Mundarija (34)

TypeScript function overload va this turi: bir funksiya — bir nechta imzo

Qisqacha: Overload — bitta funksiyaga bir nechta imzo yozish: find(id: number): Dish | undefined va find(text: string): Dish[]. Chaqiruvchi faqat shu imzolarni ko'radi, natija turi esa berilgan argumentga qarab tanlanadi. this parametri (function label(this: Dish)) funksiya qaysi obyekt ustida chaqirilishi kerakligini yozadi, : this natija turi esa bola klasslarda ham uzilmaydigan zanjir beradi.

Bu darsda

  • Overload imzolari va implementatsiya imzosini yozasiz, ularning qoidalarini bilasiz.
  • No overload matches this call kabi xabarlarni o'qiysiz.
  • Overload, union parametr va generic orasida tanlay olasiz.
  • this parametri bilan "kontekst yo'qolishi" xatosini tsc ga ushlatasiz.
  • Polimorfik this natija 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:

ts
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)); // false

Ishlaydi, 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

ts
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 2

Uch qism:

  • Overload imzolari (overload signatures) — tanasiz ikki qator. Ular chaqiruvchi uchun "menyu": find(id: number) yoki find(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:

ts
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:

text
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:

ts
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:

text
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

ts
function double(x: string): string;
function double(x: number): number {
  return x * 2;
}

Kompilyator:

text
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:

ts
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 find uchun find(2) va find("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:

ts
// ❌ 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 3

Overload 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:

ts
function describe() {
  return this.name;
}

Kompilyator:

text
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:

ts
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'm

this: 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:

ts
type Dish = { name: string; price: number };
function label(this: Dish): string {
  return this.name;
}
label();

Kompilyator:

text
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:

ts
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:

text
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 this parametrini yozing: add(this: Order, dish: string) — endi add("Osh") TS2684 beradi.
  • Callback'ni o'rang: addEventListener("click", () => order.add("Osh")).
  • Klass maydonini arrow funksiya qiling: add = (dish: string): void => { … } — arrow this ni 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:

ts
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:

text
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:

ts
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:

ts
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: OrderBuilder da add(): this, lekin build(): 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?

ts
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.

ts
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:

text
TypeError: Cannot read properties of undefined (reading 'total')
Yechim

this parametri qo'shilgach, pay(100000) TS2684 beradi. To'g'rilangan kod:

ts
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)); // 37000
  • this: Bill — chaqiruvda argument emas: bill.pay(cash) avvalgidek bitta argument oladi.
  • Ajratib olish o'rniga arrow funksiya bilan o'radik — bill.pay(...) chaqiruvida this doim bill.
  • 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 \n bilan birlashtiradi).
  • TableReceiptBuilder extends ReceiptBuilder — table(no): chek boshiga "Stol 7" qo'shadi. Zanjir add(…).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:

text
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.

ts
// 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;
  }
}
ts
// 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 esa else shoxida value number | readonly number[] bo'lib qolardi: bu tekshiruv readonly massivni chiqarib tashlamaydi (TypeScript'ning ma'lum cheklovi, tsc 7.0.2 da tekshirildi). Shuning uchun typeof qulayroq.
  • one: string va many: string[] — test overload'larni ham tekshiradi: noto'g'ri overload tanlansa, tsc shu qatorlarni to'xtatadi.
  • .replace(/\s/g, " ") — ru-RU formati minglikni uzilmas bo'sh joy bilan ajratadi (Tur annotatsiyasi darsidagi formatPrice kabi). 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:

text
✔ 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.926

XATOLAR.md ga qo'shing: TS2769, TS2575, TS2394, TS2683, TS2684. Keyin kurs/mashqlar papkasidan:

bash
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'ning fs.readFile (kodlash berilsa — string, berilmasa — Buffer). tsc xabarida "No overload matches this call" ko'rsangiz — hover'da overload ro'yxatini oching va qaysi biriga yaqin ekaningizni toping.
  • Builder va query API'lari — : this zanjirlari: so'rov yasovchilar (query.where(…).orderBy(…).limit(…)), test kutubxonalaridagi expect(…).not.toBe(…) kabi.
  • this va 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 this nima?" — 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) yoki TS2575 (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, tsc da esa noto'g'ri chaqiruvni ushlaydi (TS2684). Klass metodini ajratib olishni tsc o'zi ko'rmaydi.
  • : this natija 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 this in a Function) — typescriptlang.org/docs/handbook/2/functions.html#function-overloads
  • TypeScript Handbook: "Classes" (this Types, this parameters, Arrow Functions) — typescriptlang.org/docs/handbook/2/classes.html#this-types
  • TSConfig: noImplicitThis — typescriptlang.org/tsconfig#noImplicitThis
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
TypeScript function overload va this turi: bir funksiya — bir nechta imzo — IlmHamroh