infer kalit so'zi — conditional type ichida tur chiqarish

~20 daq · TypeScript · Ilg'or Turlar

Funksiyaning qaytish turini olish kerak — funksiyani chaqirmay. Yoki Promise ichidagi turni. infer — conditional type ichida tur "chiqarib" olish kalit so'zi.


infer nima?

infer U — conditional type ichida tur pattern matching:

type FunksiyaQaytishi<T> =
  T extends (...args: any[]) => infer R
    ? R       // ← R ni chiqarib oldik
    : never;

function soni(): number { return 42; }
function matn(): string { return ""; }

type A = FunksiyaQaytishi<typeof soni>; // number
type B = FunksiyaQaytishi<typeof matn>; // string

T funksiya bo'lsa — R qaytish turi bo'ladi. Funksiya bo'lmasa — never.


ReturnType — built-in

TypeScript da tayyor ReturnType<T> utility turi — aynan shu:

type ReturnType<T extends (...args: any) => any> =
  T extends (...args: any) => infer R ? R : any;

function hisoblash(a: number, b: number): number { return a + b; }

type A = ReturnType<typeof hisoblash>; // number

Promise ichidagi tur

type Await<T> =
  T extends Promise<infer U> ? U : T;

type A = Await<Promise<string>>;  // string
type B = Await<Promise<number>>;  // number
type C = Await<string>;           // string — Promise emas

Built-in Awaited<T> ham shu mantiq asosida (rekursiv).


Massiv elementi turi

type MassivElement<T> =
  T extends Array<infer U> ? U : never;

type A = MassivElement<string[]>;        // string
type B = MassivElement<number[]>;        // number
type C = MassivElement<(string|number)[]>; // string | number

Parametrlar turi

type Parametrlar<T extends (...args: any) => any> =
  T extends (...args: infer P) => any ? P : never;

function fn(a: string, b: number, c: boolean): void {}

type P = Parametrlar<typeof fn>; // [string, number, boolean]

Tuple dan birinchi element

type Birinchi<T extends any[]> =
  T extends [infer U, ...any[]] ? U : never;

type A = Birinchi<[string, number, boolean]>; // string
type B = Birinchi<[number]>;                  // number
type C = Birinchi<[]>;                        // never

Tez-tez uchraydigan xatolar

infer faqat extends ichida:

type Wrong<T> = infer U; // ❌ — extends dан tashqarida bo'lmaydi

type Right<T> = T extends Array<infer U> ? U : never; // ✅

Xulosa

// Funksiya qaytishi
type Qaytish<T> = T extends (...a: any[]) => infer R ? R : never;

// Promise ichidagi tur
type Kutilgan<T> = T extends Promise<infer U> ? U : T;

// Massiv elementi
type Element<T>  = T extends Array<infer U> ? U : never;

// Parametrlar
type Param<T>    = T extends (...a: infer P) => any ? P : never;

// Pattern: T extends Shakl<infer X> ? X : never
// infer — "shu joydan turni chiqar" degan buyruq

Keyingi dars

48-dars: Template literal types