TypeScript enum va as const

Oldingi darsda holatlar ro’yxati literal union bilan yozildi: "draft" | "published". Bu yozuv ishlaydi, lekin qiymatlar kod bo’ylab matn sifatida tarqaladi.

Ularni bitta joyda nom bilan saqlashning ikki yo’li bor: enum va as const. Ikkalasi bir maqsadga xizmat qiladi, lekin muhim farqi bor.

enum — nomlangan doimiylar

enum OrderStatus {
  Pending = "pending",
  Shipped = "shipped",
  Delivered = "delivered",
}

const status: OrderStatus = OrderStatus.Pending;
console.log(status);
pending

Qiymat yozilmasa, TypeScript raqam qo’yadi:

enum Direction {
  Up,
  Down,
}

console.log(Direction.Up, Direction.Down);
0 1

enum boshqa tiplardan farq qiladi

Bu darsdagi eng muhim fakt: barcha boshqa TypeScript tiplari kompilyatsiyada yo’qoladi, enum esa yo’qolmaydi.

Yuqoridagi Direction kompilyatsiyadan keyin haqiqiy JavaScript kodiga aylanadi:

var Direction;
(function (Direction) {
    Direction[Direction["Up"] = 0] = "Up";
    Direction[Direction["Down"] = 1] = "Down";
})(Direction || (Direction = {}));

Ya’ni enum tayyor faylga qo’shimcha kod qo’shadi. Qolgan tiplar — type, interface, tip izohlari — iz qoldirmaydi.

as const — enum’siz yechim

Xuddi shu natijaga oddiy obyekt bilan erishish mumkin:

const ORDER_STATUS = {
  Pending: "pending",
  Shipped: "shipped",
  Delivered: "delivered",
} as const;

console.log(ORDER_STATUS.Pending);
pending

Farqni ko’ring:

const withoutConst = { status: "pending" };
// status tipi: string

const withConst = { status: "pending" } as const;
// status tipi: "pending"

Maydonlar ham o’zgarmas bo’lib qoladi:

const config = { host: "localhost", port: 3000 } as const;
config.port = 8080;
example.ts(2,8): error TS2540: Cannot assign to 'port' because it is a read-only property.

as const dan tip olish

Obyekt yaratildi, endi undan tip chiqaramiz:

const ORDER_STATUS = {
  Pending: "pending",
  Shipped: "shipped",
  Delivered: "delivered",
} as const;

type OrderStatus = (typeof ORDER_STATUS)[keyof typeof ORDER_STATUS];

function statusLabel(status: OrderStatus): string {
  if (status === "pending") return "Kutilmoqda";
  if (status === "shipped") return "Yuborilgan";
  return "Yetkazilgan";
}

console.log(statusLabel(ORDER_STATUS.Shipped));
console.log(statusLabel("delivered"));
console.log(Object.values(ORDER_STATUS).join(", "));
Yuborilgan
Yetkazilgan
pending, shipped, delivered

Uzun qatorni qismlarga ajratamiz:

Qism Nima qiladi
typeof ORDER_STATUS Obyektning tipini oladi
keyof typeof ORDER_STATUS Kalitlar union’i: "Pending" | "Shipped" | ...
(typeof ...)[keyof ...] Qiymatlar union’i: "pending" | "shipped" | ...

Natijada OrderStatus tipi "pending" | "shipped" | "delivered" ga teng bo’ladi.

Ikkinchi qator diqqatga sazovor: statusLabel("delivered") ham ishlaydi. Ya’ni oddiy matn ham qabul qilinadi — enum da bunday bo’lmaydi.

Object.values() bilan barcha qiymatlarni ro’yxat sifatida olish mumkin — bu obyektlar darsidagi metod. enum da xuddi shu ish uchun qo’shimcha kod yozishga to’g’ri keladi.

Taqqoslash

Xususiyat enum as const
Tayyor faylga kod qo’shadi Ha Yo’q
Node.js kompilyatsiyasiz ishlatadi Yo’q Ha
Oddiy matn qabul qiladi Yo’q Ha
Qiymatlar ro’yxatini olish Qo’shimcha kod kerak Object.values()
Yozuv uzunligi Qisqa Uzunroq

Qaysi birini tanlash

  1. Yangi loyihada as const ni tanlang. U qo’shimcha kod qo’shmaydi, oddiy JavaScript obyekti bo’lib qoladi va Node.js kompilyatsiyasiz ishlatadi.
  2. Faqat ro’yxat kerak bo’lsa, literal union yetarli. type Status = "draft" | "published" — eng yengil yechim. Qiymatlarni ko’chirib yurish kerak bo’lgandagina obyekt qo’shing.
  3. Mavjud loyihada enum ishlatilgan bo’lsa, uni almashtirmang. Izchillik muhimroq.

Amaliy mashq

  1. Matn qiymatli enum e’lon qilib, uning maydonini console.log bilan chiqaring;
  2. Raqamli enum yozib, kompilyatsiyadan keyin dist ichida qanday JavaScript hosil bo’lganini ko’ring;
  3. Shu .ts faylni kompilyatsiyasiz node bilan ishga tushirib, qanday xato chiqishini kuzating;
  4. Xuddi shu ro’yxatni as const obyekt bilan qayta yozing;
  5. as const obyektidagi maydonni o’zgartirishga urinib, TS2540 xatosini o’qing;
  6. Object.values() bilan barcha qiymatlarni ro’yxat qilib chiqaring.

2 va 3-qadam juftligi eng muhimi: enum ning boshqa tiplardan farqini — tayyor faylga kod qo’shishini — o’z ko’zingiz bilan ko’rasiz.

Qisqacha xulosa

  • enum bog’liq doimiylarga umumiy nom beradi.
  • enum kompilyatsiyadan keyin yo’qolmaydi — u tayyor faylga kod qo’shadi, qolgan tiplar esa iz qoldirmaydi.
  • Node.js enum bo’lgan .ts faylini kompilyatsiyasiz ishga tushirmaydi.
  • Raqamli enum xavfli: tartib o’zgarsa, saqlangan qiymatlar ma’nosi buziladi.
  • as const obyektni o’zgarmas qiladi va maydonlarga literal tip beradi.
  • Yangi loyihada tartib shunday: avval literal union, kerak bo’lsa as const, enum esa eng oxirida.

Keyingi darsda any, unknown va never — maxsus tiplar va any nega xavfli.

Bu dars foydali bo'ldimi?

marta ko'rildi