Optional ба Readonly шинж чанар
Бодит апп дотор зарим шинж чанар заавал байх шаардлагагүй байдаг — жишээ нь хэрэглэгчийн зургийн URL эсвэл намтар. Мөн зарим утга нэг удаа тогтоогдоод хэзээ ч өөрчлөгдөх ёсгүй байдаг. TypeScript эдгээрийг ? ба readonly тэмдэглэгээгээр илэрхийлдэг.
Optional шинж чанар — ?
Шинж чанарын нэрний дараа ? тавивал тухайн шинж чанар заавал биш болно:
interface Хэрэглэгч {
нэр: string; // заавал
и_мэйл: string; // заавал
намтар?: string; // заавал биш
зураг?: string; // заавал биш
вэбсайт?: string; // заавал биш
}
// Зөвхөн заавал шинж чанараар — зөв
const хэрэглэгч1: Хэрэглэгч = {
нэр: "Болд",
и_мэйл: "bold@example.mn",
};
// Нэмэлт шинж чанараар — мөн зөв
const хэрэглэгч2: Хэрэглэгч = {
нэр: "Сарнай",
и_мэйл: "sarnai@example.mn",
намтар: "TypeScript хөгжүүлэгч",
зураг: "https://example.mn/sarnai.jpg",
};
Optional шинж чанарын төрөл нь автоматаар string | undefined болдог тул ашиглахаасаа өмнө шалгах хэрэгтэй:
function профайл харах(хэрэглэгч: Хэрэглэгч): void {
console.log(хэрэглэгч.нэр);
// Шалгалтгүйгээр ашиглавал алдаа гарч болно
// console.log(хэрэглэгч.намтар.toUpperCase()); // Алдаа!
// Зөв арга — optional chaining ?. ашиглана
console.log(хэрэглэгч.намтар?.toUpperCase() ?? "Намтар бичээгүй байна");
}
?. гэдэг нь "байвал ашигла, байхгүй бол undefined буцаа" гэсэн утгатай. ?? нь "зүүн тал undefined бол баруун талыг ашигла" гэсэн утгатай.
Readonly шинж чанар
readonly тавивал тухайн шинж чанарыг эхний удаа тохируулсны дараа өөрчлөх боломжгүй болно:
interface Хэрэглэгч {
readonly id: string; // өөрчлөгдөхгүй
readonly үүссэн: string; // өөрчлөгдөхгүй
нэр: string; // өөрчлөгдөж болно
и_мэйл: string; // өөрчлөгдөж болно
}
const хэрэглэгч: Хэрэглэгч = {
id: "usr_abc123",
үүссэн: "2024-01-15",
нэр: "Болд",
и_мэйл: "bold@example.mn",
};
хэрэглэгч.нэр = "Мөнхбат"; // зөв — readonly биш
хэрэглэгч.id = "usr_xyz"; // Алдаа! id readonly
хэрэглэгч.үүссэн = "2024-06-01"; // Алдаа! үүссэн readonly
readonly нь өгөгдлийн бүрэн бүтэн байдлыг хамгаалдаг. Хэрэглэгчийн id санамсаргүйгээр өөрчлөгдөх ёсгүй — TypeScript компайлын үед л тэр алдааг баригдана.
Хоёуланг хамтад нь ашиглах
Optional ба readonly нэг дор хэрэглэж болно:
interface Нийтлэл {
readonly id: string;
readonly зохиогч: string;
гарчиг: string;
агуулга: string;
зураг?: string; // заавал биш, өөрчлөгдөж болно
readonly нийтлэгдсэн?: string; // заавал биш, өөрчлөгдөхгүй
шошгонууд?: string[]; // заавал биш массив
}
const нийтлэл: Нийтлэл = {
id: "post_001",
зохиогч: "Болд",
гарчиг: "TypeScript сурах нь",
агуулга: "...",
шошгонууд: ["typescript", "хөгжүүлэлт"],
};
нийтлэл.гарчиг = "TypeScript сурах бүрэн гарын авлага"; // зөв
нийтлэл.зохиогч = "Сарнай"; // Алдаа! readonly
Readonly массив
Массивыг ч readonly болгож болно:
interface Курс {
гарчиг: string;
readonly хичээлүүд: readonly string[];
}
const курс: Курс = {
гарчиг: "TypeScript",
хичээлүүд: ["Үндэс", "Interface", "Generic"],
};
курс.хичээлүүд.push("Decorator"); // Алдаа! readonly массивт нэмж болохгүй
курс.хичээлүүд = []; // Алдаа! readonly шинж чанарт оноож болохгүй
readonly string[] нь массивын агуулгыг ч, оноолтыг ч хаана.
Бодит жишээ: API хариу
API-аас ирсэн өгөгдөл өөрчлөгдөх ёсгүй тохиолдолд readonly ашиглах нь зөв дадал:
interface АПИХариу {
readonly statusCode: number;
readonly timestamp: string;
readonly requestId: string;
өгөгдөл?: unknown;
алдааны мессеж?: string;
}
function хариу боловсруулах(хариу: АПИХариу): void {
if (хариу.statusCode === 200) {
console.log("Амжилттай:", хариу.өгөгдөл);
} else {
console.log("Алдаа:", хариу.алдааны мессеж ?? "Тодорхойгүй алдаа");
}
// хариу.statusCode = 201; // Алдаа! API хариуг өөрчлөх боломжгүй
}
Дараагийн хичээлд:
Interface-г өөр interface-ээс өвлөх (extends) аргыг судална. Энэ нь нийтлэг шинж чанарыг давтахгүйгээр шинэ interface үүсгэх боломж олгодог.