any ба unknown төрлүүд
TypeScript-ийн хамгийн хүчирхэг тал нь төрлийн систем. Гэхдээ заримдаа өгөгдлийн төрлийг урьдчилан мэдэх боломжгүй байна. Тэгэхэд any ба unknown нь ажлыг гүйцэтгэдэг — гэхдээ тэдгээрийг хэрхэн ашиглах нь чухал.
any — бүх хаалгыг нээх
any бол TypeScript-ийн төрлийн шалгалтыг бүрэн унтраадаг тусгай төрөл. any зарласан хувьсагчид дурын утга оруулах, дурын аргыг дуудах боломжтой.
let өгөгдөл: any = "мөр";
өгөгдөл = 42; // Алдаа байхгүй
өгөгдөл = true; // Алдаа байхгүй
өгөгдөл = [1, 2, 3]; // Алдаа байхгүй
өгөгдөл.байхгүй арга(); // Алдаа байхгүй — гэхдээ ажиллах үед CRASH болно!
TypeScript any утгад ямар ч шалгалт хийдэггүй. Энэ нь дараах асуудал үүсгэдэг:
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 хувьсагчийг ашиглахын өмнө төрлийг шалгах шаардлагатай.
let өгөгдөл: unknown = "мөр";
өгөгдөл = 42; // Алдаа байхгүй — оноох боломжтой
өгөгдөл = true; // Алдаа байхгүй
// Шалгалтгүйгээр ашиглах боломжгүй
console.log(өгөгдөл.toUpperCase()); // Алдаа! Төрлийг шалгаагүй
TypeScript unknown утгыг ашиглахаас өмнө заавал шалга гэж шаарддаг:
let утга: unknown = "Сайн уу, дэлхий!";
// typeof ашиглан шалгана
if (typeof утга === "string") {
console.log(утга.toUpperCase()); // САЙН УУ, ДЭЛХИЙ! — аюулгүй
}
if (typeof утга === "number") {
console.log(утга * 2); // энэ блок ажиллахгүй
}
typeof шалгалтын дараа TypeScript тухайн блок доторх төрлийг мэддэг болдог. Үүнийг type narrowing гэнэ.
any ба unknown харьцуулалт
// any — шалгалтгүйгээр бүгдийг зөвшөөрнө
let аюулттай: any = getExternalData();
аюулттай.байхгүй_арга(); // TypeScript алдаа гаргахгүй — гэхдээ ажиллах үед crash
// unknown — шалгалт шаардана
let аюулгүй: unknown = getExternalData();
аюулгүй.байхгүй_арга(); // TypeScript АЛДАА ГАРГАНА — энэ сайн!
if (typeof аюулгүй === "string") {
аюулгүй.toUpperCase(); // Одоо аюулгүй
}
| Шинж чанар | any | unknown |
| ------------------ | ----- | --------- |
| Дурын утга оноох | Тийм | Тийм |
| Шалгалтгүй ашиглах | Тийм | Үгүй |
| Алдааг илрүүлэх | Үгүй | Тийм |
| Аюулгүй байдал | Бага | Өндөр |
Бодит хэрэглээ: API хариу боловсруулах
API-аас өгөгдөл авахад төрлийг урьдчилан мэдэхгүй байдаг. unknown ашигласнаар аюулгүй шалгана:
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 төрлүүдийг судална. Нэг хувьсагч хэд хэдэн өөр төрлийн утга авч болох тохиолдолд хэрхэн илэрхийлэх вэ?