TypeScript tasdiqlash funksiyalari bo'yicha to'liq qo'llanma. Kompilyatsiya va dastur ishlash vaqtidagi tiplar xavfsizligini ta'minlash, ma'lumotlarni tekshirish va mustahkam kod yozishni o'rganing.
TypeScript Tasdiqlash Funksiyalari: Dastur Ishlash Vaqtidagi Tiplar Xavfsizligi Bo'yicha To'liq Qo'llanma
Veb-dasturlash olamida kodingiz kutayotgan natijalar va u qabul qiladigan ma'lumotlarning haqiqati o'rtasidagi kelishuv ko'pincha mo'rt bo'ladi. TypeScript son-sanoqsiz xatoliklarni ishlab chiqarishga yetib bormasdan oldin ushlab qoluvchi kuchli statik tiplar tizimini taqdim etish orqali JavaScript yozish uslubimizni inqilob qildi. Biroq, bu xavfsizlik tarmog'i asosan kompilyatsiya vaqtida mavjud bo'ladi. Sizning chiroyli tiplashtirilgan ilovangiz dastur ishlash vaqtida tashqi dunyodan tartibsiz, oldindan aytib bo'lmaydigan ma'lumotlarni qabul qilsa nima bo'ladi? Aynan shu yerda TypeScript'ning tasdiqlash funksiyalari haqiqatan ham mustahkam ilovalar yaratish uchun ajralmas vositaga aylanadi.
Ushbu keng qamrovli qo'llanma sizni tasdiqlash funksiyalari bilan chuqur tanishtiradi. Biz ularning nima uchun zarurligini, ularni noldan qanday yaratishni va ularni keng tarqalgan real hayotiy stsenariylarga qanday qo'llashni o'rganamiz. Yakunda siz nafaqat kompilyatsiya vaqtida tiplar xavfsizligini ta'minlaydigan, balki dastur ishlash vaqtida ham chidamli va bashorat qilinadigan kod yozishga tayyor bo'lasiz.
Katta Bo'linish: Kompilyatsiya Vaqti va Dastur Ishlash Vaqti
Tasdiqlash funksiyalarining qadriga yetish uchun biz avvalo ular hal qiladigan asosiy muammoni tushunishimiz kerak: TypeScript'ning kompilyatsiya vaqti dunyosi va JavaScript'ning dastur ishlash vaqti dunyosi o'rtasidagi bo'shliq.
TypeScript'ning Kompilyatsiya Vaqtidagi Jannati
Siz TypeScript kodini yozganingizda, dasturchining jannatida ishlaysiz. TypeScript kompilyatori (tsc
) hushyor yordamchi sifatida ishlaydi va kodingizni siz belgilagan tiplarga muvofiq tahlil qiladi. U quyidagilarni tekshiradi:
- Funksiyalarga noto'g'ri tiplarning uzatilishi.
- Obyektda mavjud bo'lmagan xususiyatlarga kirish.
null
yokiundefined
bo'lishi mumkin bo'lgan o'zgaruvchini chaqirish.
Bu jarayon kodingiz ishga tushirilishidan oldin sodir bo'ladi. Yakuniy natija barcha tip izohlaridan tozalangan oddiy JavaScript bo'ladi. TypeScript'ni bino uchun batafsil arxitektura chizmasi deb tasavvur qiling. U barcha rejalar mustahkam, o'lchamlar to'g'ri va strukturaning yaxlitligi qog'ozda kafolatlanganligini ta'minlaydi.
JavaScript'ning Dastur Ishlash Vaqtidagi Haqiqati
TypeScript kodingiz JavaScript'ga kompilyatsiya qilinib, brauzerda yoki Node.js muhitida ishga tushgach, statik tiplar yo'qoladi. Endi sizning kodingiz dinamik, oldindan aytib bo'lmaydigan dastur ishlash vaqti dunyosida ishlaydi. U o'zi nazorat qila olmaydigan manbalardan keladigan ma'lumotlar bilan ishlashi kerak, masalan:
- API Javoblari: Backend xizmati o'zining ma'lumotlar strukturasini kutilmaganda o'zgartirishi mumkin.
- Foydalanuvchi Kiritgan Ma'lumotlar: HTML formalaridan olingan ma'lumotlar kiritish turidan qat'i nazar, har doim satr (string) sifatida qabul qilinadi.
- Local Storage:
localStorage
'dan olingan ma'lumotlar har doim satr bo'ladi va uni qayta ishlash (parse) kerak. - Muhit O'zgaruvchilari: Ular ko'pincha satrlar bo'ladi va umuman mavjud bo'lmasligi ham mumkin.
Bizning o'xshatishimizdan foydalansak, dastur ishlash vaqti - bu qurilish maydoni. Chizma mukammal edi, ammo yetkazib berilgan materiallar (ma'lumotlar) noto'g'ri o'lchamda, noto'g'ri turda yoki shunchaki yetishmayotgan bo'lishi mumkin. Agar siz ushbu nuqsonli materiallar bilan qurishga harakat qilsangiz, sizning inshootingiz qulaydi. Aynan shu yerda dastur ishlash vaqtida xatoliklar yuzaga keladi, bu esa ko'pincha "Cannot read properties of undefined" kabi ishdan chiqishlar va xatoliklarga olib keladi.
Tasdiqlash Funksiyalari Kirib Keladi: Bo'shliqni To'ldirish
Xo'sh, biz TypeScript chizmamizni dastur ishlash vaqtining oldindan aytib bo'lmaydigan materiallariga qanday tatbiq etamiz? Bizga ma'lumotlarni *kelishi bilanoq* tekshirib, ular bizning kutganimizga mos kelishini tasdiqlaydigan mexanizm kerak. Tasdiqlash funksiyalari aynan shu vazifani bajaradi.
Tasdiqlash Funksiyasi Nima?
Tasdiqlash funksiyasi TypeScript'dagi maxsus turdagi funksiya bo'lib, ikkita muhim maqsadga xizmat qiladi:
- Dastur Ishlash Vaqtidagi Tekshiruv: U qiymat yoki shartni tekshiradi. Agar tekshiruv muvaffaqiyatsiz bo'lsa, u xatolik chiqaradi va shu kod yo'lining bajarilishini darhol to'xtatadi. Bu yaroqsiz ma'lumotlarning ilovangizga yanada tarqalishini oldini oladi.
- Kompilyatsiya Vaqtidagi Tipni Toraytirish: Agar tekshiruv muvaffaqiyatli o'tsa (ya'ni, xato chiqmasa), u TypeScript kompilyatoriga qiymatning tipi endi aniqroq ekanligini bildiradi. Kompilyator bu tasdiqlashga ishonadi va sizga qiymatni uning qamrov doirasining qolgan qismida tasdiqlangan tip sifatida ishlatishga ruxsat beradi.
Sehr funksiya imzosida bo'lib, u asserts
kalit so'zidan foydalanadi. Uning ikkita asosiy shakli mavjud:
asserts condition [is type]
: Bu shakl ma'lum bircondition
rost (truthy) ekanligini tasdiqlaydi. O'zgaruvchining tipini toraytirish uchun ixtiyoriy ravishdais type
(tip predikati) ni qo'shishingiz mumkin.asserts this is type
: Bu klass metodlari ichidathis
kontekstining tipini tasdiqlash uchun ishlatiladi.
Asosiy xulosa - bu "muvaffaqiyatsizlikda xato chiqarish" xususiyati. Oddiy if
tekshiruvidan farqli o'laroq, tasdiqlash shunday deydi: "Dasturning davom etishi uchun bu shart to'g'ri bo'lishi shart. Agar unday bo'lmasa, bu istisno holat va biz darhol to'xtashimiz kerak."
Birinchi Tasdiqlash Funksiyangizni Yaratish: Amaliy Misol
Keling, JavaScript va TypeScript'dagi eng keng tarqalgan muammolardan biri - potensial null
yoki undefined
qiymatlar bilan ishlashdan boshlaylik.
Muammo: Keraksiz Null'lar
Ixtiyoriy foydalanuvchi obyektini qabul qiladigan va foydalanuvchi nomini log'ga chiqarmoqchi bo'lgan funksiyani tasavvur qiling. TypeScript'ning qat'iy null tekshiruvlari bizni potensial xatolik haqida to'g'ri ogohlantiradi.
interface User {
name: string;
email: string;
}
function logUserName(user: User | undefined) {
// 🚨 TypeScript Xatosi: 'user' 'undefined' bo'lishi mumkin.
console.log(user.name.toUpperCase());
}
Buni tuzatishning standart usuli if
tekshiruvi bilan:
function logUserName(user: User | undefined) {
if (user) {
// Bu blok ichida TypeScript 'user' 'User' tipida ekanligini biladi.
console.log(user.name.toUpperCase());
} else {
console.error('User is not provided.');
}
}
Bu ishlaydi, lekin agar bu kontekstda `user`ning `undefined` bo'lishi tuzatib bo'lmaydigan xatolik bo'lsa-chi? Biz funksiyaning jimgina davom etishini xohlamaymiz. Biz uning baland ovozda ishdan chiqishini xohlaymiz. Bu takrorlanuvchi himoya bandlariga olib keladi.
Yechim: `assertIsDefined` Tasdiqlash Funksiyasi
Keling, bu naqshni oqlangan tarzda hal qilish uchun qayta ishlatiladigan tasdiqlash funksiyasini yarataylik.
// Bizning qayta ishlatiladigan tasdiqlash funksiyamiz
function assertIsDefined<T>(value: T, message: string = "Value is not defined"): asserts value is NonNullable<T> {
if (value === undefined || value === null) {
throw new Error(message);
}
}
// Keling, uni ishlatamiz!
interface User {
name: string;
email: string;
}
function logUserName(user: User | undefined) {
assertIsDefined(user, "User object must be provided to log name.");
// Xato yo'q! TypeScript endi 'user' 'User' tipida ekanligini biladi.
// Tip 'User | undefined' dan 'User' ga toraytirildi.
console.log(user.name.toUpperCase());
}
// Foydalanish misoli:
const validUser = { name: 'Alice', email: 'alice@example.com' };
logUserName(validUser); // "ALICE" ni log'ga chiqaradi
const invalidUser = undefined;
try {
logUserName(invalidUser); // Xatolik chiqaradi: "User object must be provided to log name."
} catch (error) {
console.error(error.message);
}
Tasdiqlash Imzosini Tahlil Qilish
Keling, asserts value is NonNullable<T>
imzosini tahlil qilaylik
asserts
: Bu funksiyani tasdiqlash funksiyasiga aylantiradigan maxsus TypeScript kalit so'zi.value
: Bu funksiyaning birinchi parametriga (bizning holatda `value` nomli o'zgaruvchiga) ishora qiladi. U TypeScript'ga qaysi o'zgaruvchining tipi toraytirilishi kerakligini aytadi.is NonNullable<T>
: Bu tip predikati. U kompilyatorga, agar funksiya xato chiqarmasa, `value`ning tipi endiNonNullable<T>
ekanligini aytadi. TypeScript'dagiNonNullable
yordamchi tipi tipdannull
vaundefined
'ni olib tashlaydi.
Tasdiqlash Funksiyalari Uchun Amaliy Foydalanish Holatlari
Endi biz asoslarni tushunganimizdan so'ng, keng tarqalgan, real hayotiy muammolarni hal qilish uchun tasdiqlash funksiyalarini qanday qo'llashni ko'rib chiqaylik. Ular eng kuchli bo'lgan joy - bu ilovangizning chegaralari, ya'ni tashqi, tiplanmagan ma'lumotlar tizimingizga kiradigan joylar.
Foydalanish Holati 1: API Javoblarini Tekshirish
Bu, shubhasiz, eng muhim foydalanish holatidir. fetch
so'rovidan olingan ma'lumotlar tabiatan ishonchsizdir. TypeScript `response.json()` natijasini to'g'ri `Promise
Stsenariy
Biz API'dan foydalanuvchi ma'lumotlarini olyapmiz. Biz uning `User` interfeysimizga mos kelishini kutamiz, ammo bunga amin bo'la olmaymiz.
interface User {
id: number;
name: string;
email: string;
}
// Oddiy tip himoyachisi (boolean qaytaradi)
function isUser(data: unknown): data is User {
return (
typeof data === 'object' &&
data !== null &&
'id' in data && typeof (data as any).id === 'number' &&
'name' in data && typeof (data as any).name === 'string' &&
'email' in data && typeof (data as any).email === 'string'
);
}
// Bizning yangi tasdiqlash funksiyamiz
function assertIsUser(data: unknown): asserts data is User {
if (!isUser(data)) {
throw new TypeError('Invalid User data received from API.');
}
}
async function fetchAndProcessUser(userId: number) {
const response = await fetch(`https://api.example.com/users/${userId}`);
const data: unknown = await response.json();
// Chegarada ma'lumotlar shaklini tasdiqlang
assertIsUser(data);
// Shu nuqtadan boshlab, 'data' xavfsiz tarzda 'User' sifatida tiplanadi.
// Endi 'if' tekshiruvlari yoki tip o'zgartirishlariga hojat yo'q!
console.log(`Processing user: ${data.name.toUpperCase()} (${data.email})`);
}
fetchAndProcessUser(1);
Nima uchun bu kuchli: Javobni olgandan so'ng darhol `assertIsUser(data)` ni chaqirish orqali biz "xavfsizlik darvozasi"ni yaratamiz. Undan keyingi har qanday kod `data`ni ishonch bilan `User` sifatida ishlata oladi. Bu tekshirish mantiqini biznes mantiqidan ajratadi, bu esa ancha toza va o'qilishi oson kodga olib keladi.
Foydalanish Holati 2: Muhit O'zgaruvchilarining Mavjudligini Ta'minlash
Server tomonidagi ilovalar (masalan, Node.js'da) konfiguratsiya uchun muhit o'zgaruvchilariga qattiq tayanadi. `process.env.MY_VAR` ga kirish `string | undefined` tipini beradi. Bu sizni uni ishlatadigan har bir joyda uning mavjudligini tekshirishga majbur qiladi, bu esa zerikarli va xatoliklarga moyil.
Stsenariy
Ilovamizning ishlashi uchun muhit o'zgaruvchilaridan API kaliti va ma'lumotlar bazasi URL manzili kerak. Agar ular mavjud bo'lmasa, ilova ishlay olmaydi va darhol aniq xato xabari bilan to'xtashi kerak.
// Yordamchi faylda, masalan, 'config.ts'
export function getEnvVar(key: string): string {
const value = process.env[key];
if (value === undefined) {
throw new Error(`FATAL: Environment variable ${key} is not set.`);
}
return value;
}
// Tasdiqlashlar yordamida yanada kuchliroq versiya
function assertEnvVar(key: string): asserts key is keyof NodeJS.ProcessEnv {
if (process.env[key] === undefined) {
throw new Error(`FATAL: Environment variable ${key} is not set.`);
}
}
// Ilovangizning kirish nuqtasida, masalan, 'index.ts'
function startServer() {
// Barcha tekshiruvlarni ishga tushirishda bajaring
assertEnvVar('API_KEY');
assertEnvVar('DATABASE_URL');
const apiKey = process.env.API_KEY;
const dbUrl = process.env.DATABASE_URL;
// TypeScript endi apiKey va dbUrl 'string | undefined' emas, balki 'string' ekanligini biladi.
// Ilovangiz kerakli konfiguratsiyaga ega ekanligi kafolatlanadi.
console.log('API Key length:', apiKey.length);
console.log('Connecting to DB:', dbUrl.toLowerCase());
// ... serverni ishga tushirish mantiqining qolgan qismi
}
startServer();
Nima uchun bu kuchli: Bu naqsh "tezda-ishdan-chiqish" (fail-fast) deb ataladi. Siz barcha muhim konfiguratsiyalarni ilovangizning hayotiy siklining boshida bir marta tekshirasiz. Agar muammo bo'lsa, u darhol tavsiflovchi xato bilan ishdan chiqadi, bu esa keyinroq yetishmayotgan o'zgaruvchi nihoyat ishlatilganda sodir bo'ladigan sirli ishdan chiqishni tuzatishdan ancha osonroqdir.
Foydalanish Holati 3: DOM Bilan Ishlash
DOM'ga so'rov yuborganingizda, masalan, `document.querySelector` bilan, natija `Element | null` bo'ladi. Agar siz element mavjudligiga amin bo'lsangiz (masalan, asosiy ilova ildizi `div`), doimiy ravishda `null` uchun tekshirish noqulay bo'lishi mumkin.
Stsenariy
Bizda `
` bo'lgan HTML fayl bor va skriptimiz unga kontent biriktirishi kerak. Biz uning mavjudligini bilamiz.
// Avvalgi umumiy tasdiqlashimizdan qayta foydalanish
function assertIsDefined<T>(value: T, message: string = "Value is not defined"): asserts value is NonNullable<T> {
if (value === undefined || value === null) {
throw new Error(message);
}
}
// DOM elementlari uchun maxsusroq tasdiqlash
function assertQuerySelector<T extends Element>(selector: string, constructor?: new () => T): T {
const element = document.querySelector(selector);
assertIsDefined(element, `FATAL: Element with selector '${selector}' not found in the DOM.`);
// Ixtiyoriy: bu to'g'ri turdagi element ekanligini tekshirish
if (constructor && !(element instanceof constructor)) {
throw new TypeError(`Element '${selector}' is not an instance of ${constructor.name}`);
}
return element as T;
}
// Foydalanish
const appRoot = document.querySelector('#app-root');
assertIsDefined(appRoot, 'Could not find the main application root element.');
// Tasdiqlashdan so'ng, appRoot 'Element | null' emas, balki 'Element' tipida bo'ladi.
appRoot.innerHTML = 'Hello, World!
';
// Maxsusroq yordamchidan foydalanish
const submitButton = assertQuerySelector<HTMLButtonElement>('#submit-btn', HTMLButtonElement);
// 'submitButton' endi to'g'ri tarzda HTMLButtonElement sifatida tiplanadi
submitButton.disabled = true;
Nima uchun bu kuchli: Bu sizga o'z muhitingiz haqida invariantni — siz to'g'ri deb bilgan shartni ifodalashga imkon beradi. Bu shovqinli null-tekshiruv kodini olib tashlaydi va skriptning ma'lum bir DOM tuzilishiga bog'liqligini aniq hujjatlashtiradi. Agar tuzilma o'zgarsa, siz darhol aniq xatoga duch kelasiz.
Tasdiqlash Funksiyalari va Alternativlar
Tasdiqlash funksiyasini tip himoyachilari yoki tip kastingi kabi boshqa tipni toraytirish usullariga nisbatan qachon ishlatishni bilish juda muhim.
Texnika | Sintaksis | Muvaffaqiyatsizlikdagi holati | Eng yaxshi qo'llanilishi |
---|---|---|---|
Tip himoyachilari | value is Type |
false qaytaradi |
Boshqaruv oqimi (if/else ). "Noqulay" holat uchun haqiqiy, alternativ kod yo'li mavjud bo'lganda. Masalan, "Agar bu string bo'lsa, uni qayta ishlang; aks holda, standart qiymatdan foydalaning." |
Tasdiqlash funksiyalari | asserts value is Type |
Error chiqaradi |
Invariantlarni majburlash. Dasturning to'g'ri davom etishi uchun shart to'g'ri bo'lishi kerak bo'lganda. "Noqulay" yo'l tuzatib bo'lmaydigan xatolikdir. Masalan, "API javobi User obyekti bo'lishi kerak." |
Tip o'zgartirish (kasting) | value as Type |
Ishlash vaqtida ta'siri yo'q | Siz, dasturchi, kompilyatordan ko'proq biladigan va kerakli tekshiruvlarni allaqachon bajargan kamdan-kam holatlar uchun. Bu ishlash vaqtida nol xavfsizlikni ta'minlaydi va tejamkorlik bilan ishlatilishi kerak. Haddan tashqari foydalanish "kod hidi" (code smell) hisoblanadi. |
Asosiy Qo'llanma
O'zingizdan so'rang: "Agar bu tekshiruv muvaffaqiyatsiz bo'lsa, nima bo'lishi kerak?"
- Agar qonuniy alternativ yo'l bo'lsa (masalan, foydalanuvchi autentifikatsiyadan o'tmagan bo'lsa, kirish tugmasini ko'rsatish),
if/else
bloki bilan tip himoyachisidan foydalaning. - Agar muvaffaqiyatsiz tekshiruv dasturingiz yaroqsiz holatda ekanligini va xavfsiz davom eta olmasligini anglatsa, tasdiqlash funksiyasidan foydalaning.
- Agar siz kompilyatorni dastur ishlash vaqtida tekshiruvsiz bekor qilsangiz, siz tip o'zgartirish (kasting) dan foydalanayapsiz. Juda ehtiyot bo'ling.
Ilg'or Naqshlar va Eng Yaxshi Amaliyotlar
1. Markaziy Tasdiqlash Kutubxonasini Yarating
Tasdiqlash funksiyalarini kodingiz bo'ylab tarqatib yubormang. Ularni src/utils/assertions.ts
kabi maxsus yordamchi faylda markazlashtiring. Bu qayta foydalanish, izchillikni targ'ib qiladi va tekshirish mantiqini topish va sinovdan o'tkazishni osonlashtiradi.
// src/utils/assertions.ts
export function assert(condition: unknown, message: string): asserts condition {
if (!condition) {
throw new Error(message);
}
}
export function assertIsDefined<T>(value: T): asserts value is NonNullable<T> {
assert(value !== null && value !== undefined, 'This value must be defined.');
}
export function assertIsString(value: unknown): asserts value is string {
assert(typeof value === 'string', 'This value must be a string.');
}
// ... va hokazo.
2. Mazmunli Xatolar Chiqaring
Muvaffaqiyatsiz tasdiqlashdan kelib chiqadigan xato xabari disk raskadrovka paytidagi birinchi ishorangizdir. Uni qimmatli qiling! "Tasdiqlash muvaffaqiyatsiz bo'ldi" kabi umumiy xabar yordam bermaydi. Buning o'rniga kontekstni taqdim eting:
- Nima tekshirilayotgan edi?
- Qanday kutilgan qiymat/tip bor edi?
- Haqiqatda qanday qiymat/tip qabul qilindi? (Maxfiy ma'lumotlarni log'ga chiqarmaslikka ehtiyot bo'ling).
function assertIsUser(data: unknown): asserts data is User {
if (!isUser(data)) {
// Yomon: throw new Error('Yaroqsiz ma'lumot');
// Yaxshi:
throw new TypeError(`Expected data to be a User object, but received ${JSON.stringify(data)}`);
}
}
3. Ishlash Unumdorligini Yodda tuting
Tasdiqlash funksiyalari dastur ishlash vaqtidagi tekshiruvlardir, ya'ni ular protsessor sikllarini iste'mol qiladi. Bu ilovangizning chegaralarida (API kirishi, konfiguratsiyani yuklash) mutlaqo maqbul va keraklidir. Biroq, murakkab tasdiqlashlarni sekundiga minglab marta ishlaydigan qattiq sikl kabi ishlash unumdorligi uchun muhim bo'lgan kod yo'llari ichiga joylashtirishdan saqlaning. Ularni tekshirish xarajati bajarilayotgan operatsiyaga (masalan, tarmoq so'rovi) nisbatan ahamiyatsiz bo'lgan joylarda ishlating.
Xulosa: Ishonch Bilan Kod Yozish
TypeScript tasdiqlash funksiyalari shunchaki tor doiradagi xususiyat emas; ular mustahkam, ishlab chiqarish darajasidagi ilovalarni yozish uchun asosiy vositadir. Ular sizga kompilyatsiya vaqti nazariyasi va dastur ishlash vaqti haqiqati o'rtasidagi muhim bo'shliqni to'ldirish imkonini beradi.
Tasdiqlash funksiyalarini qabul qilish orqali siz quyidagilarni amalga oshirishingiz mumkin:
- Invariantlarni Majburlash: To'g'ri bo'lishi kerak bo'lgan shartlarni rasman e'lon qilib, kodingiz taxminlarini aniq qiling.
- Tez va Shovqinli Xatoga Uchrang: Ma'lumotlar yaxlitligi muammolarini manbada ushlang, ularning keyinchalik nozik va disk raskadrovka qilish qiyin bo'lgan xatoliklarga sabab bo'lishini oldini oling.
- Kod AniqliÄŸini Yaxshilang: Ichki joylashgan
if
tekshiruvlari va tip o'zgartirishlarini olib tashlang, natijada toza, chiziqliroq va o'z-o'zini hujjatlashtiradigan biznes mantiqi hosil bo'ladi. - Ishonchni Oshiring: Tiplaringiz nafaqat kompilyator uchun takliflar, balki kod bajarilganda faol ravishda majburlanishiga ishonch bilan kod yozing.
Keyingi safar API'dan ma'lumot olganingizda, konfiguratsiya faylini o'qiganingizda yoki foydalanuvchi kiritgan ma'lumotlarni qayta ishlaganingizda, shunchaki tipni o'zgartirib, eng yaxshisiga umid qilmang. Uni tasdiqlang. Tizimingiz chekkasida xavfsizlik darvozasini quring. Kelajakdagi o'zingiz va jamoangiz siz yozgan mustahkam, bashorat qilinadigan va chidamli kod uchun sizga minnatdorchilik bildiradi.