Function interface — chaqiriladigan tur, construct signature

~15 daq · TypeScript · Interface

Funksiyani parametr sifatida qabul qiladigan funksiya yozmoqchisiz. TypeScript bu funksiyaning qanday shaklda bo'lishi kerakligini bilishi kerak:

function bajar(callback) { // callback nima tur?
  callback(42);
}

Funksiya turi uchun ham interface yozish mumkin — bu function interface (chaqiriladigan tur).


Funksiya uchun interface

Odatda funksiya turini shu tarzda yoziladi:

type Hisoblash = (a: number, b: number) => number;

Interface bilan ham yozish mumkin — call signature sintaksisi:

interface Hisoblash {
  (a: number, b: number): number;
}

Ikkalasi bir xil ishlaydi:

const qoshish: Hisoblash = (a, b) => a + b;
const ayirish: Hisoblash = (a, b) => a - b;

function hisoblash(fn: Hisoblash, x: number, y: number): number {
  return fn(x, y);
}

hisoblash(qoshish, 10, 5); // 15
hisoblash(ayirish, 10, 5); // 5

Funksiya + xususiyatlar — birgalikda

Interface ning kuchi shunda: funksiya ham chaqirilishi, ham xususiyatga ega bo'lishi mumkin:

interface Qayta {
  (xabar: string): void;    // chaqirish turi
  maqsad: string;           // xususiyat
  logLevel: "info" | "xato"; // xususiyat
}

Bu JavaScript da keng tarqalgan pattern — masalan express ning app ob'ekti ham funksiya ham, app.get() kabi metodlarga ham ega.

function qaytaYaratish(maqsad: string): Qayta {
  const fn = (xabar: string) => {
    console.log(`[${fn.maqsad}] ${xabar}`);
  };
  fn.maqsad   = maqsad;
  fn.logLevel = "info" as const;
  return fn;
}

const logger = qaytaYaratish("API");
logger("So'rov keldi");     // [API] So'rov keldi
logger.maqsad;              // "API"

Construct signature — new bilan chaqirish

Ba'zan funksiya new bilan chaqirilishi kerak — ya'ni constructor. Buning uchun new kalit so'zi ishlatiladi:

interface Konstruktor {
  new (ism: string): { ism: string; salomlash(): string };
}

function yaratish(K: Konstruktor, ism: string) {
  return new K(ism);
}

class Kishi {
  constructor(public ism: string) {}
  salomlash() { return `Salom, ${this.ism}!`; }
}

yaratish(Kishi, "Jasur"); // ✅

Bu ayniqsa factory pattern da foydali — turli classlarni bir xil interfeysga moslab ishlatish.


Overload — bir nechta imzo

Interface da funksiya bir nechta turli imzoga ega bo'lishi mumkin:

interface Qidirish {
  (id: number):   Foydalanuvchi;
  (email: string): Foydalanuvchi;
}

Funksiya number ham, string ham qabul qiladi — har biri uchun alohida imzo.


Tez-tez uchraydigan xatolar

Call signature va method sintaksisini chalkashtirib yuborish:

interface A {
  fn(x: number): void;  // metod sintaksisi
}

interface B {
  fn: (x: number) => void; // xususiyat sifatida funksiya
}

interface C {
  (x: number): void;    // call signature — ob'ektning o'zi chaqiriladi
}

A va B — ob'ektning fn metodi. C — ob'ektning o'zi funksiya sifatida chaqiriladi.


Xulosa

// Oddiy funksiya turi
interface Hisoblash {
  (a: number, b: number): number;
}

// Funksiya + xususiyatlar
interface Logger {
  (xabar: string): void;
  daraja: string;
}

// Constructor
interface Fabrika {
  new (ism: string): Mahsulot;
}

Funksiya interface — funksiya turini aniq belgilash va bir vaqtda xususiyatlarga ega bo'lish uchun. Callback, factory, plugin tizimlarida keng ishlatiladi.


Keyingi dars

20-dars: Interface vs Type alias — qachon qaysi, farqlari