Recursive types — o'ziga murojaat qiladigan turlar

~15 daq · TypeScript · Ilg'or Turlar

Daraxt tuzilmasi: har tugun bolalar turgunlarga ega bo'lishi mumkin, ular ham bolalarga ega. Bu tuzilmani oddiy interfaceda ifodalab bo'lmaydi — recursive type kerak: o'ziga murojaat qiladigan tur.


Recursive type

type DaraxtTugun<T> = {
  qiymat:   T;
  bolalar?: DaraxtTugun<T>[]; // o'ziga murojaat
};

const daraxt: DaraxtTugun<string> = {
  qiymat: "ildiz",
  bolalar: [
    {
      qiymat: "1-bola",
      bolalar: [
        { qiymat: "1.1-bola" },
        { qiymat: "1.2-bola" },
      ]
    },
    { qiymat: "2-bola" },
  ]
};

JSON turi

type JSONQiymat =
  | string
  | number
  | boolean
  | null
  | JSONQiymat[]           // massiv elementlari ham JSONQiymat
  | { [key: string]: JSONQiymat }; // ob'ekt xususiyatlari ham JSONQiymat

const json: JSONQiymat = {
  ism: "Jasur",
  yosh: 25,
  manzil: { shahar: "Toshkent" },
  hobbies: ["kitob", "kod"],
};

Kategoriya daraxt

interface Kategoriya {
  id:         number;
  nomi:       string;
  bolalar:    Kategoriya[]; // o'ziga murojaat
}

const kategoriyalar: Kategoriya = {
  id: 1, nomi: "Elektronika",
  bolalar: [
    { id: 2, nomi: "Telefonlar",  bolalar: [] },
    { id: 3, nomi: "Noutbuklar",  bolalar: [
      { id: 4, nomi: "Gaming", bolalar: [] },
    ]},
  ]
};

Recursive mapped type

// Barcha ichki ob'ektlarni ham readonly qilish
type DeepReadonly<T> = {
  readonly [K in keyof T]: T[K] extends object
    ? DeepReadonly<T[K]>
    : T[K];
};

type Config = { db: { host: string; port: number }; ssl: boolean };
type ReadonlyConfig = DeepReadonly<Config>;
// { readonly db: { readonly host: string; readonly port: number }; readonly ssl: boolean }

Tez-tez uchraydigan xatolar

Cheksiz rekursiya:

type A = A[]; // ❌ — Type alias 'A' circularly references itself

Rekursiya to'g'ri tuzilishi kerak — har doim "baza holati" bo'lishi shart.

Juda chuqur rekursiya:

TypeScript rekursiya chuqurligini cheklaydi (taxminan 100 daraja). Juda chuqur daraxtta xato bo'lishi mumkin.


Xulosa

// Daraxt
type Tugun<T> = { qiymat: T; bolalar?: Tugun<T>[] };

// JSON
type JSON =
  | string | number | boolean | null
  | JSON[]
  | { [k: string]: JSON };

// Deep recursive
type DeepPartial<T> = {
  [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
};

Recursive type — tuzilma o'zi bilan belgilanadi. JSON, daraxt, ro'yxat kabi cheksiz chuqur tuzilmalar uchun.


Keyingi dars

50-dars: Utility Types — Partial, Required, Readonly, Record