5-bo‘lim

Funksiya turlari

Parametr va qaytish turlari, kontekstli turlash, void ning kutilmagan qoidasi, ortiqcha yuklash.

🕑 29 daqiqa o‘qish 📄 907 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Parametr va qaytish turi
  2. Qaytish turini yozish shartmi?
  3. Ixtiyoriy va standart parametrlar
  4. Argument soni tekshiriladi
  5. Qolgan parametrlar
  6. Funksiya turi ifodasi
  7. Kontekstli turlash
  8. Kutilmagan qoida: void
  9. Parametr soni: kam bo'lishi mumkin, ko'p bo'lishi yo'q
  10. Ortiqcha yuklash
  11. never qaytaruvchi funksiya
  12. Obyekt ichidagi funksiyalar
  13. Xulosa

Funksiya - dasturda turlar eng ko'p foyda keltiradigan joy. U qanday ma'lumot qabul qilishini va nima qaytarishini bir qarashda aytib turadi.

Bu bobda yana bir kutilmagan qoida bor - void bilan bog'liq.

Parametr va qaytish turi #

TS
function chegirma(narx: number, foiz: number): number {
  return narx - (narx * foiz) / 100;
}

console.log(chegirma(50000, 20));
Terminal
tsx src/asos.ts
Natija
40000

(narx: number, foiz: number): number - qavs ichida parametrlar, qavsdan keyin qaytish turi.

Qaytish turini yozish shartmi? #

Yozmasangiz, TypeScript uni o'zi xulosa qiladi:

TS
function sarlavha() {
  return 42;
}

const s: string = sarlavha();
Terminal
tsc --noEmit 2>&1 | fold -sw 74
Natija
src/xulosa.ts(5,7): error TS2322: Type 'number' is not assignable to type
'string'.

Xato 5-qatorda - ishlatilgan joyda. Endi qaytish turini yozib qo'yamiz:

TS
function sarlavha(): string {
  return 42;
}
Terminal
tsc --noEmit 2>&1 | fold -sw 74
Natija
src/xulosa2.ts(2,3): error TS2322: Type 'number' is not assignable to
type 'string'.

Xato 2-qatorda - muammo tug'ilgan joyda.

Qaytish turini yozing

Ikkala holatda ham xato tutildi, lekin ikkinchisi yaxshiroq:

  • xato manbada ko'rsatiladi, ishlatilgan joyda emas;
  • funksiya nima qaytarishi shartnomaga aylanadi - ichini o'zgartirsangiz, chaqiruvchilar buzilmaydi;
  • katta funksiyada TypeScript ning xulosasi kutganingizdan farq qilishi mumkin.

Ichki, qisqa yordamchi funksiyalarda esa xulosaga tayanish bemalol.

Ixtiyoriy va standart parametrlar #

TS
function salom(ism: string, unvon?: string): string {
  return unvon ? `${unvon} ${ism}` : ism;
}

function narxla(narx: number, valyuta: string = "som"): string {
  return `${narx} ${valyuta}`;
}

console.log(salom("Husanboy"));
console.log(salom("Husanboy", "Admin"));
console.log(narxla(12000));
console.log(narxla(12000, "USD"));
Terminal
tsx src/param.ts
Natija
Husanboy
Admin Husanboy
12000 som
12000 USD
YozuvTuriBerilmasa
unvon: stringstringXato
unvon?: stringstring | undefinedundefined
valyuta: string = "som"string"som"

Standart qiymatli parametrda ? yozilmaydi va turi undefined bo'lmaydi - qiymat doim bor.

Argument soni tekshiriladi #

JavaScript da ortiqcha argument e'tiborsiz qoladi, yetishmagani undefined bo'ladi. TypeScript da ikkalasi ham xato:

TS
function chegirma(narx: number, foiz: number): number {
  return narx;
}

chegirma(50000);
chegirma(50000, 20, 30);
Terminal
tsc --noEmit 2>&1 | fold -sw 74
Natija
src/soni.ts(5,1): error TS2554: Expected 2 arguments, but got 1.
src/soni.ts(6,21): error TS2554: Expected 2 arguments, but got 3.

Ixtiyoriy parametr majburiysidan oldin kelolmaydi - aks holda qaysi argument qayerga tushishini aniqlab bo'lmaydi:

TS
function yomon(a?: number, b: number) {
  return 0;
}
Terminal
tsc --noEmit 2>&1 | fold -sw 74
Natija
src/tartib.ts(1,28): error TS1016: A required parameter cannot follow an
optional parameter.

Qolgan parametrlar #

TS
function jami(...sonlar: number[]): number {
  return sonlar.reduce((a, b) => a + b, 0);
}

console.log(jami());
console.log(jami(1, 2, 3));
console.log(jami(...[10, 20, 30]));
Terminal
tsx src/qolgan.ts
Natija
0
6
60

...sonlar ning turi massiv bo'lishi shart - number[], ya'ni "nechta bo'lsa ham, har biri son".

Funksiya turi ifodasi #

Funksiyaning o'zini ham tur sifatida yozish mumkin:

TS
type Formatla = (narx: number) => string;

const somda: Formatla = (n) => `${n} som`;
const dollarda: Formatla = (n) => `$${(n / 12500).toFixed(2)}`;

function chop(narx: number, f: Formatla): void {
  console.log(f(narx));
}

chop(12000, somda);
chop(12000, dollarda);
Terminal
tsx src/tur.ts
Natija
12000 som
$0.96

(narx: number) => string - "son qabul qilib, satr qaytaradigan funksiya". Bu yerda => tur yozuvi, strelkali funksiya emas.

E'tibor bering: somda va dollarda ichida n ga hech qanday tur yozilmagan.

Kontekstli turlash #

TypeScript funksiyaning qayerga berilayotganini ko'rib, parametr turini o'zi topadi:

TS
const mahsulotlar = ["Olma", "Anor"];
mahsulotlar.forEach((m) => console.log(m.toUpperCase()));
Terminal
tsx src/kontekst.ts
Natija
OLMA
ANOR

m ning string ekanini hech kim yozmadi - forEach ning turi shuni aytib turibdi. Va bu xatoni ham tutadi:

TS
const mahsulotlar = ["Olma", "Anor"];
const x = mahsulotlar.map((m) => m * 2);
Terminal
tsc --noEmit 2>&1 | fold -sw 74
Natija
src/kontekst2.ts(2,34): error TS2362: The left-hand side of an arithmetic
operation must be of type 'any', 'number', 'bigint' or an enum type.

3-bobda ko'rgan TS7006 (yashirin any) aynan kontekst yo'qligida chiqadi. Kontekst bo'lsa - annotatsiya kerak emas.

Kutilmagan qoida: void #

void "hech narsa qaytarmaydi" degani. Lekin qiymat qaytaradigan funksiya ham void turiga mos keladi:

TS
type Ishlov = (nomi: string) => void;

const royxat: string[] = [];
const qosh: Ishlov = (nomi) => royxat.push(nomi);

qosh("Olma");
qosh("Anor");
console.log(royxat.length);
Terminal
tsc --noEmit && echo "tsc: xato yo_q"
tsx src/void1.ts
Natija
tsc: xato yo_q
2

royxat.push(nomi) son qaytaradi. Tur esa void deyapti. Xato yo'q.

Ikkinchi yarmi bundan ham qiziq:

TS
type Ishlov = (nomi: string) => void;

const uzunlik: Ishlov = (nomi) => nomi.length;
const natija = uzunlik("Olma");
console.log(natija);

const son: number = uzunlik("Olma");
Terminal
tsx src/void2.ts
echo "--- tsc ---"
tsc --noEmit 2>&1 | fold -sw 74
Natija
4
--- tsc ---
src/void2.ts(7,7): error TS2322: Type 'void' is not assignable to type
'number'.

Ish vaqtida 4 qaytdi. Tur tizimi esa "bu void" deb turibdi va uni songa berishga ruxsat bermadi.

void: berish mumkin, olish mumkin emas Berish - ruxsat type Ishlov = (n: string) => void const q: Ishlov = (n) => royxat.push(n) push son qaytaradi - lekin xato yo'q Sabab: natija baribir ishlatilmaydi Olish - taqiq const natija = q("Olma") const son: number = q("Olma") TS2322: void ni number ga bo'lmaydi Ish vaqtida esa 4 qaytadi Lekin: void ni ELON QILIB qiymat qaytarish - xato function hech(): void { return 42; } TS2322: Type 'number' is not assignable to type 'void'. Amaliy foyda: royxat.forEach((m) => royxat2.push(m)) yozish mumkin. Bu qoida bo'lmasa, har bir bunday qator xato berardi.
void ga berish erkin, voiddan qiymat olish esa taqiqlangan

E'lon qilingan void da esa return qiymat bilan kelolmaydi:

TS
function hech(): void {
  return 42;
}
Terminal
tsc --noEmit 2>&1 | fold -sw 74
Natija
src/void3.ts(2,3): error TS2322: Type 'number' is not assignable to type
'void'.
Nega shunday bo'lgani muhim

Bu qoida bo'lmasa, quyidagi juda oddiy kod xato berardi:

Natija
const yangi: string[] = [];
eski.forEach((m) => yangi.push(m));

push son qaytaradi, forEach esa void kutadi. Qoida bo'lmasa har bir shunday qator uchun { } qavs yozib chiqish kerak bo'lardi.

Shuning uchun TypeScript: "void - natijaga qiziqmayman degani, qaytarmasin degani emas" deb qaraydi.

Parametr soni: kam bo'lishi mumkin, ko'p bo'lishi yo'q #

TS
type Ishlov = (nomi: string, indeks: number) => void;

const oddiy: Ishlov = (nomi) => console.log(nomi);
oddiy("Olma", 0);
Terminal
tsx src/kam.ts
Natija
Olma

Ikkita parametr kutilayotgan joyga bitta parametrli funksiya berildi - va bu to'g'ri. Aynan shu sabab forEach((m) => ...) deb yozganda indeks va massivni tashlab ketish mumkin.

Teskarisi esa ishlamaydi:

TS
type Bir = (nomi: string) => void;

const kop: Bir = (nomi: string, indeks: number) => {
  console.log(nomi, indeks);
};
Terminal
tsc --noEmit 2>&1 | fold -sw 74
Natija
src/kop.ts(3,7): error TS2322: Type '(nomi: string, indeks: number) =>
void' is not assignable to type 'Bir'.
  Target signature provides too few arguments. Expected 2 or more, but
got 1.

Mantiq oddiy: chaqiruvchi bitta argument beradi, funksiya esa ikkitasini kutadi - ikkinchisi doim undefined bo'lardi.

Ortiqcha yuklash #

Bir funksiya turli argumentlarda turli natija qaytarsa:

TS
function qidir(id: number): string;
function qidir(nomi: string): number;
function qidir(x: number | string): string | number {
  return typeof x === "number" ? "Olma" : 12000;
}

const a = qidir(1);
const b = qidir("Olma");
console.log(a, b);
Terminal
tsx src/yukla.ts
Natija
Olma 12000

a ning turi string, b niki number - aralash string | number emas. Uchinchi qator - amalga oshirish imzosi, u tashqaridan chaqirilmaydi:

TS
function qidir(id: number): string;
function qidir(nomi: string): number;
function qidir(x: number | string): string | number {
  return typeof x === "number" ? "Olma" : 12000;
}

qidir(true);
Terminal
tsc --noEmit 2>&1 | fold -sw 74
Natija
src/yukla2.ts(7,7): error TS2769: No overload matches this call.
  Overload 1 of 2, '(id: number): string', gave the following error.
    Argument of type 'boolean' is not assignable to parameter of type
'number'.
  Overload 2 of 2, '(nomi: string): number', gave the following error.
    Argument of type 'boolean' is not assignable to parameter of type
'string'.

boolean amalga oshirish imzosiga mos kelmasa ham, TypeScript faqat ikkita e'lon qilingan variantni tekshiradi.

Ortiqcha yuklashni ortiqcha ishlatmang

Ko'p hollarda union yoki generik aniqroq va soddaroq chiqadi. Ortiqcha yuklash chindan kerak bo'ladigan joy - argument turi qaytish turini butunlay o'zgartirganda.

Generiklarni 9-bobda ko'ramiz.

never qaytaruvchi funksiya #

TS
function xatoBer(xabar: string): never {
  throw new Error(xabar);
}

function tekshir(n: number): string {
  if (n < 0) xatoBer("manfiy son");
  return "yaxshi";
}

console.log(tekshir(5));
Terminal
tsx src/never.ts
Natija
yaxshi

never - "bu funksiya hech qachon normal tugamaydi". U yo xato tashlaydi, yo abadiy ishlaydi. void bilan aralashtirmang: void funksiya tugaydi, shunchaki qiymat qaytarmaydi.

Obyekt ichidagi funksiyalar #

TS
type Dokon = {
  nomi: string;
  narxla(mahsulot: string): number;
  chegirma: (narx: number) => number;
};

const d: Dokon = {
  nomi: "Dokon",
  narxla(m) {
    return m.length * 1000;
  },
  chegirma: (n) => n * 0.9,
};

console.log(d.narxla("Olma"), d.chegirma(10000));
Terminal
tsx src/metod.ts
Natija
4000 9000

Ikkala yozuv ham ishlaydi:

YozuvNomi
narxla(m: string): numberMetod yozuvi
chegirma: (n: number) => numberXossa yozuvi

Farqi deyarli yo'q; metod yozuvi obyekt metodlariga ko'proq mos tushadi. narxla(m) da m ning turi yana kontekstdan olindi.

Xulosa #

  • Funksiyada parametr turlari qavs ichida, qaytish turi qavsdan keyin yoziladi.
  • Qaytish turini yozib qo'yish xatoni manbada ko'rsatadi, ishlatilgan joyda emas.
  • ? ixtiyoriy parametrni belgilaydi; standart qiymatli parametrda ? kerak emas va turi undefined bo'lmaydi.
  • Ixtiyoriy parametr majburiysidan oldin kelolmaydi (TS1016).
  • Argument soni qat'iy tekshiriladi - kam ham, ko'p ham xato (TS2554).
  • ...qolgan: T[] cheksiz argument qabul qiladi; uning turi massiv bo'lishi shart.
  • (a: number) => string - funksiya turi ifodasi; bu yerdagi => tur yozuvi.
  • Kontekstli turlash: funksiya qayerga berilayotgani parametr turlarini o'zi aniqlaydi - forEach((m) => ...).
  • void turiga qiymat qaytaradigan funksiyani berish mumkin, lekin natijani qiymat sifatida olish mumkin emas.
  • void deb e'lon qilingan funksiyaning o'zi esa qiymat qaytarolmaydi.
  • Kam parametrli funksiya ko'p parametrli turga mos keladi; teskarisi yo'q.
  • Ortiqcha yuklashda amalga oshirish imzosi tashqaridan chaqirilmaydi; never esa normal tugamaydigan funksiya.
Amaliy topshiriq
  1. Ikki parametrli, qaytish turi yozilgan funksiya yarating.
  2. Qaytish turini olib tashlab, xato qaysi qatorga ko'chganini ko'ring.
  3. Ixtiyoriy va standart qiymatli parametrli funksiya yozing; ikkalasining turini taqqoslang.
  4. Ixtiyoriy parametrni majburiysidan oldin qo'yib, TS1016 ni chaqiring.
  5. ...sonlar: number[] bilan o'rtachani hisoblovchi funksiya yozing.
  6. type Formatla = (n: number) => string turini yarating va unga ikkita turli amalga oshirish bering.
  7. map ichidagi parametrga hech qanday tur yozmasdan, uni noto'g'ri ishlatib xato oling.
  8. void qaytaruvchi turga push chaqiradigan funksiya bering va xato yo'qligini tasdiqlang.
  9. O'sha funksiyaning natijasini number ga berishga urinib, TS2322 ni oling.
  10. Ikkita variantli ortiqcha yuklash yozing va noto'g'ri turdagi argument bilan chaqirib, TS2769 xabarini o'qing.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.