TypeScript / any ба unknown төрлүүд

any ба unknown төрлүүд

TypeScript-ийн хамгийн хүчирхэг тал нь төрлийн систем. Гэхдээ заримдаа өгөгдлийн төрлийг урьдчилан мэдэх боломжгүй байна. Тэгэхэд any ба unknown нь ажлыг гүйцэтгэдэг — гэхдээ тэдгээрийг хэрхэн ашиглах нь чухал.

any — бүх хаалгыг нээх

any бол TypeScript-ийн төрлийн шалгалтыг бүрэн унтраадаг тусгай төрөл. any зарласан хувьсагчид дурын утга оруулах, дурын аргыг дуудах боломжтой.

typescript
let өгөгдөл: any = "мөр";
өгөгдөл = 42;         // Алдаа байхгүй
өгөгдөл = true;       // Алдаа байхгүй
өгөгдөл = [1, 2, 3];  // Алдаа байхгүй

өгөгдөл.байхгүй арга(); // Алдаа байхгүй — гэхдээ ажиллах үед CRASH болно!

TypeScript any утгад ямар ч шалгалт хийдэггүй. Энэ нь дараах асуудал үүсгэдэг:

typescript
function нэмэх(a: any, b: any): any {
  return a + b;
}

console.log(нэмэх(5, 10)); // 15 — зөв
console.log(нэмэх("5", 10)); // "510" — буруу! Мөр нийлэв
console.log(нэмэх(true, false)); // 1 — буруу! Boolean нэмэгдэв

TypeScript алдаа гаргасангүй — гэхдээ үр дүн нь буруу. any ашигласнаар TypeScript-г JavaScript шиг болгодог.

any-г хэзээ ашиглах вэ?

Практик дээр any ашиглахгүй байхыг хичээх хэрэгтэй. Зөвхөн дараах тохиолдолд ашиглаж болно:

  • JavaScript кодыг TypeScript руу шилжүүлж байгаа үед (түр зуур)
  • Гуравдагч талын library-д төрлийн мэдэгдэл байхгүй үед

tsconfig.json"noImplicitAny": true тохиргоо хийснээр TypeScript any-г автоматаар нэмэхийг хориглоно.

unknown — аюулгүй альтернатив

unknown нь any-тай адил боловч аюулгүй хувилбар. unknown хувьсагчийг ашиглахын өмнө төрлийг шалгах шаардлагатай.

typescript
let өгөгдөл: unknown = "мөр";
өгөгдөл = 42; // Алдаа байхгүй — оноох боломжтой
өгөгдөл = true; // Алдаа байхгүй

// Шалгалтгүйгээр ашиглах боломжгүй
console.log(өгөгдөл.toUpperCase()); // Алдаа! Төрлийг шалгаагүй

TypeScript unknown утгыг ашиглахаас өмнө заавал шалга гэж шаарддаг:

typescript
let утга: unknown = "Сайн уу, дэлхий!";

// typeof ашиглан шалгана
if (typeof утга === "string") {
  console.log(утга.toUpperCase()); // САЙН УУ, ДЭЛХИЙ! — аюулгүй
}

if (typeof утга === "number") {
  console.log(утга * 2); // энэ блок ажиллахгүй
}

typeof шалгалтын дараа TypeScript тухайн блок доторх төрлийг мэддэг болдог. Үүнийг type narrowing гэнэ.

any ба unknown харьцуулалт

typescript
// any — шалгалтгүйгээр бүгдийг зөвшөөрнө
let аюулттай: any = getExternalData();
аюулттай.байхгүй_арга(); // TypeScript алдаа гаргахгүй — гэхдээ ажиллах үед crash

// unknown — шалгалт шаардана
let аюулгүй: unknown = getExternalData();
аюулгүй.байхгүй_арга(); // TypeScript АЛДАА ГАРГАНА — энэ сайн!

if (typeof аюулгүй === "string") {
  аюулгүй.toUpperCase(); // Одоо аюулгүй
}

| Шинж чанар | any | unknown | | ------------------ | ----- | --------- | | Дурын утга оноох | Тийм | Тийм | | Шалгалтгүй ашиглах | Тийм | Үгүй | | Алдааг илрүүлэх | Үгүй | Тийм | | Аюулгүй байдал | Бага | Өндөр |

Бодит хэрэглээ: API хариу боловсруулах

API-аас өгөгдөл авахад төрлийг урьдчилан мэдэхгүй байдаг. unknown ашигласнаар аюулгүй шалгана:

typescript
async function хэрэглэгч авах(id: number): Promise<unknown> {
  const хариу = await fetch(`/api/users/${id}`);
  return хариу.json();
}

const өгөгдөл: unknown = await хэрэглэгч авах(1);

// Шалгалтгүйгээр ашиглах боломжгүй
// console.log(өгөгдөл.нэр); // Алдаа!

// Төрлийг шалгасны дараа л ашиглана
if (
  typeof өгөгдөл === "object" &&
  өгөгдөл !== null &&
  "нэр" in өгөгдөл
) {
  console.log((өгөгдөл as { нэр: string }).нэр);
}

Энэ нь any ашиглахаас хамаагүй найдвартай. Шалгалт хийснээр null эсвэл буруу бүтцийн улмаас crash болохоос сэргийлнэ.

Дүгнэлт: аль нэгийг сонгох

  • any: зайлсхийгээрэй. Зөвхөн хуучин JavaScript кодыг шилжүүлэхэд болон яаралтай prototype хийхэд л ашиглана.
  • unknown: API хариу, хэрэглэгчийн оролт, гадаад өгөгдөл боловсруулахад ашиглана. Шалгалт хийх шаардлагатай тул кодоо аюулгүй байлгадаг.

Сайн TypeScript кодонд any тохиолдох нь маш ховор байна.

Дараагийн хичээлд:

Union ба Intersection төрлүүдийг судална. Нэг хувьсагч хэд хэдэн өөр төрлийн утга авч болох тохиолдолд хэрхэн илэрхийлэх вэ?