ჰოი ჰოი! 👋
მე ვარ @nyaomaru, ფრონტენდ ინჟინერი, რომელსაც საშინელებები ეშინია 🙀
გილოცავთ ჰელოუინს! 🎃👻
დღეს ღამით ჩვენ შევისწავლით ერთ მოჩვენებით TypeScript პროექტს.
იქ არიან ზომბები 🧟, მოჩვენებები 👻, საიდუმლო ვეშაპები 🎃 და საშინელი ვამპირი 🧛, რომლებიც ჩვენ გველოდებიან.
და ყველა მათგანს TypeScript-ის ტიპებთან აქვს საერთო რამე!
ჩვენი მისია?
გადავრჩეთ ღამე ტიპების უსაფრთხოების დაკარგვის გარეშე! 😸
წავედით!
🧟 თავი 1: უცნობი ცოცხალი მკვდრები
ბნელი და საშინელი ღამეა.
უცბად, სამარიდან რაღაც ამოძვრება! 🧟
const creature: unknown = JSON.parse('{"message":"BRAAAINS!"}');
ოჰ! უცნობი არსება!
ვნახოთ, რა უნდა მას.
console.log(creature.message);
// ❌ 'creature' is of type 'unknown'.
რა?! 🙀
TypeScript არ გვაძლევს საშუალებას!
მაგრამ რატომ?
იმიტომ, რომ ზუსტად არ ვიცით, რა არის creature.
შესაძლოა ზომბი იყოს.
შესაძლოა მოჩვენება.
შესაძლოა პატარა, ლამაზი კატაც კი. 😸
unknown ნიშნავს, რომ მნიშვნელობა ჯერ არ გვაქვს შემოწმებული.
განსხვავებით any-სგან, TypeScript არ მოგვცემს უფლებას, unknown მნიშვნელობის ნებისმიერ თვისებას მივმართოთ.
და ეს ნამდვილად კარგია!
სცადოთ რამე უფრო მარტივი.
import { isString } from "is-kit";
const voice: unknown = JSON.parse('"BRAAAINS!"');
if (isString(voice)) {
console.log(voice.toUpperCase());
// BRAAAINS!
}
ვაიჰ! 🎉
ჩვენ გადავურჩით პირველ შეხვედრას!
რა თქმა უნდა, აქ შეგვეძლო typeof voice === 'string'-ის გამოყენებაც.
ერთჯერადი შემოწმებისთვის ეს სრულიად კარგია!
მაგრამ რა ხდება, როცა ჩვენი მონსტრები უფრო დიდი და რთული ხდებიან?
🎃 თავი 2: დიდი საიდუმლო ვეშაპი
შეხედეთ!
გიგანტური ვეშაპი! 🎃
და როგორც ჩანს, ის კანფეტებით არის სავსე.
მაგრამ არავინ იცის, რა არის შიგნით სინამდვილეში.
const pumpkin: unknown = JSON.parse(`{
"name": "Big Pumpkin",
"candies": ["Chocolate", "Lollipop", "Cookie"],
"spookyLevel": 99,
"keeper": {
"name": "cat",
"friendly": true
},
"secret": "Meow!"
}`);
ეს საკმაოდ დიდი ობიექტია.
შეგვიძლია უბრალოდ კანფეტის აღება?
console.log(pumpkin.candies);
// ❌ 'pumpkin' is of type 'unknown'.
ისევ! 😿
რამეს შეხებამდე უნდა შევამოწმოთ, რა არის შიგნით.
საბედნიეროდ, გვაქვს struct!
import {
arrayOf,
isBoolean,
isNumber,
isString,
optionalKey,
struct,
} from "is-kit";
const isPumpkin = struct({
name: isString,
candies: arrayOf(isString),
spookyLevel: isNumber,
keeper: struct({
name: isString,
friendly: isBoolean,
}),
secret: optionalKey(isString),
});
ჩვენ რამდენიმე პატარა გუარდი ერთ დიდ ვეშაპის გუარდად შევაერთეთ.
-
isStringამოწმებს სტრიქონებს. -
isNumberამოწმებს სასრულ რიცხვებს. -
arrayOf(isString)ამოწმებს სტრიქონების მასივს. -
structამოწმებს ჩადგმული ობიექტების სტრუქტურას. -
optionalKeyთვისებას საშუალებას აძლევს, იყოს არარსებული.
ახლა გავხსნათ ვეშაპი!
import { safeParse } from "is-kit";
const result = safeParse(isPumpkin, pumpkin);
if (result.valid) {
console.log(result.value.candies);
// ['Chocolate', 'Lollipop', 'Cookie']
console.log(result.value.keeper.name);
// cat 😸
}
კანფეტი ვიპოვეთ!!! 🍬🎉
როცა ვალიდაცია წარმატებულია, result.value-ს აქვს ტიპი, რომელიც ჩვენი გუარდებიდან გამოიცნობა.
ხოლო როცა ვალიდაცია ვერ ხერხდება?
const cursedPumpkin = {
name: "Cursed Pumpkin",
candies: "100 candies",
spookyLevel: 99,
keeper: {
name: "cat",
friendly: true,
},
};
const result = safeParse(isPumpkin, cursedPumpkin);
console.log(result);
// { valid: false }
კანფეტები სტრიქონი იყო და არა მასივი!
ჩვენმა გუარდმა წყევლილი ვეშაპი უარყო.
და აქ მთავარი ნაწილია.
safeParse არ ასწორებს და არ გარდაქმნის არასწორ მნიშვნელობებს სასწაულებრივად.
ის მხოლოდ გვეუბნება, გაიარა თუ არა მნიშვნელობამ ჩვენი გუარდი.
ასევე, struct ნაგულისხმევად იძლევა დამატებით თვისებებს. თუ გსურთ დამატებითი საკუთარი, ჩართული სტრიქონული გასაღებების უარყოფა, შეგიძლიათ გამოიყენოთ { exact: true }.
მარტივი და მოსახერხებელია!
🍬 თავი 3: ხრიკი თუ მკურნალობა!
დინ-დონ! 🔔
TRICK OR TREAT!!! 😸
ვიღაც გვაძლევს საიდუმლო საჩუქარს.
function receiveGift(): unknown {
return Math.random() > 0.5 ? "Chocolate" : { spiders: 100 };
}
const gift: unknown = receiveGift();
მოიცადეთ.
ეს კანფეტია?
თუ ობობებით სავსე ყუთი?! 🕷️😱
გვჭირდება გზა, რომ შევამოწმოთ!
და ამჯერად გვსურს, მივიღოთ ან სტრიქონი, ან რიცხვი.
მოდით, გუარდები or-ით გავაერთიანოთ!
import { isNumber, isString, or } from "is-kit";
const isTreat = or(isString, isNumber);
function trickOrTreat(gift: unknown) {
if (isTreat(gift)) {
// gift: string | number
return `🍬 Treat: ${gift}`;
}
return "👻 Trick!";
}
ახლა სცადოთ!
trickOrTreat("Chocolate");
// 🍬 Treat: Chocolate
trickOrTreat(100);
// 🍬 Treat: 100
trickOrTreat({ spiders: 100 });
// 👻 Trick!
ვაიჰ!!! 🍬
დღეს ობობები არ გვემუქრება!
ეს ერთ-ერთი ჩემი საყვარელი რამეა is-kit-ში.
ერთ დიდ ვალიდატორს არ გვჭირდება.
შეგვიძლია ავაშენოთ პატარა გუარდები, შევაერთოთ ისინი და ხელახლა გამოვიყენოთ, სადაც საჭიროა.
პატარა გუარდები. მარტივი კომპოზიცია. სასარგებლო TypeScript-ის ვიწროება.
აი, იდეა!
მაგრამ მოიცადეთ,
რაღაც მოდის.
რაღაც საშინელი.
🧛 ფინალური ბოსი: ვამპირი, სახელად any
უცბად ფარნები ქრება.
კარი იღება.
ბნელში საიდუმლო ფიგურა ჩნდება.
ეს... COUNT ANY!!! 🧛💀
ყველაზე საშინელი ვამპირი ჩვენს TypeScript პროექტში! და მას ძალიან საშიში ძალა აქვს.
მას შეუძლია, TypeScript-ს შეაჩეროს ჩვენი ოპერაციების შემოწმება!
const visitor: unknown = JSON.parse('{"name":666}');
იდუმალი სტუმარი მოვიდა.
ჩვეულებრივ, TypeScript გვიცავს იმისგან, რომ თვისებებს შევამოწმებამდე არ მივმართოთ.
მაგრამ Count Any-ს ხრიკი აქვს.
THE CURSE OF as any! 🧛
const vampire = visitor as any;
// The vampire ignores type safety!
console.log(vampire.name.toUpperCase());
TypeScript-ის შეცდომა არ არის!
მოიცადე, რა?! 🙀
ეს ნიშნავს, რომ კოდი უსაფრთხოა?
გაშვებისას
TypeError: vampire.name.toUpperCase is not a function
💀 GAME OVER 💀
Count Any-მა რიცხვი სტრიქონად არ გადააქცია.
მან უბრალოდ დაარწმუნა TypeScript, რომ ეს არ შეემოწმებინა!
სწორედ ეს ხდის any-ს საშიშს.
ის საშუალებას გაძლევს, შეასრულო ოპერაციები იმის დადასტურების გარეშე, რომ ისინი იმუშავებენ.
მაგრამ unknown სხვანაირად იქცევა.
const visitor: unknown = JSON.parse('{"name":666}');
console.log(visitor.name.toUpperCase());
// ❌ TypeScript stops us!
TypeScript არ გააგრძელებს, სანამ მნიშვნელობას არ შევამოწმებთ.
ასე რომ, როგორ დავამარცხოთ Count Any?
რა თქმა უნდა, Type Guard-ით! 😸
import { isString, struct } from "is-kit";
const isFriendlyGuest = struct({
name: isString,
});
if (isFriendlyGuest(visitor)) {
console.log(visitor.name.toUpperCase());
} else {
console.log("🧄 Not tonight, Count Any!");
}
და ასე უცებ
ვამპირი დამარცხდა! 🧄🎉
რა თქმა უნდა, ამ კონკრეტული წყეული მნიშვნელობა მაინც უარყოფილია.
Type Guard ამოწმებს რეალურ მნიშვნელობას გაშვებისას, მაშინ როცა ტიპის მინიშნება მხოლოდ იმას ცვლის, რას ფიქრობს TypeScript მის შესახებ.
ერთი მნიშვნელოვანი დეტალი: არც unknown და არც any არ ცვლის მნიშვნელობას გაშვებისას.
ისინი TypeScript-ის ტიპებია.
განსხვავება იმაშია, რას აძლევს კომპილატორი უფლებას გავაკეთოთ მნიშვნელობის შემოწმებამდე.
და სწორედ ამიტომ არის unknown ხშირად უფრო უსაფრთხო არჩევანი არაენდობა მონაცემებისთვის.
😸 ეპილოგი: ჰელოუინი გადავიტანეთ!
რა ღამე!
ჩვენ შევხვდით უცნობ ცოცხალ მკვდრებს, გავხსენით გიგანტური ვეშაპი, შევაგროვეთ კანფეტები და დავამარცხეთ Count Any!
ასე რომ, რა ვისწავლეთ?
| მონსტრი | TypeScript-ის გაკვეთილი |
|---|---|
| 🧟 უცნობი ცოცხალი მკვდრები |
unknown ხელს უშლის შეუმოწმებელ ოპერაციებს |
| 🎃 დიდი ვეშაპი |
struct ამოწმებს ობიექტების სტრუქტურას |
| 🍬 ხრიკი თუ მკურნალობა |
or აერთიანებს ხელახლა გამოსაყენებელ Type Guard-ებს |
| 🧛 Count Any |
any გვერდს უვლის ჩვეულებრივ ტიპების შემოწმებას |
რა თქმა უნდა, any ყოველთვის ბოროტი არ არის.
ზოგჯერ ის სასარგებლოა ძველ კოდთან ან რთულ ინტეგრაციებთან მუშაობისას.
მაგრამ API-ის პასუხებთან, დამუშავებულ JSON-თან და სხვა არანდობილ მნიშვნელობებთან მუშაობისას, მათი unknown-ად შენარჩუნება ვალიდაციამდე ხშირად გაცილებით უსაფრთხო მიდგომაა.
და is-kit ამ შემოწმებებს მარტივად ასაწყობს და ხელახლა გამოსაყენებელს ხდის!
თუ მეტის გაგება გსურთ, გადახედეთ ოფიციალურ გიდს 👇
📖 How to Validate unknown in TypeScript Without a Schema Library
და გახსოვდეთ
ნამდვილი მონსტრი unknown არ არის. ეს შეუმოწმებელი any-ია. 🧛
გილოცავთ ჰელოუინს!!! 🎃👻
თუ ეს პატარა TypeScript თავგადასავალი მოგეწონათ, გადახედეთ is-kit-ს!
nyaomaru
/
is-kit
შექმენით პატარა გუარდები. შეაერთეთ ისინი. მსუბუქი, დამოკიდებულებების გარეშე მოქმედი ინსტრუმენტარიუმი ხელახლა გამოსაყენებელი TypeScript Type Guard-ების შესაქმნელად, რომლებიც ერთმანეთს ერწყმიან, აზუსტებენ და ინარჩუნებენ ბუნებრივ ვიწროებას. გაშვებისას უსაფრთხო 🛡️, კომპოზიციური 🧩 და ერგონომიული ✨.
is-kitშექმენით პატარა გუარდები. შეაერთეთ ისინი.
is-kit არის მსუბუქი, დამოკიდებულებების გარეშე მოქმედი ინსტრუმენტარიუმი ხელახლა გამოსაყენებელი TypeScript type guard-ების შესაქმნელად.
is-kit არ არის მხოლოდ isX დამხმარეების კოლექცია. მისი მთავარი მიზანია პატარა გაშვების დროის შემოწმებების კომპოზიცია ხელახლა გამოსაყენებელ გუარდებად, TypeScript-ის სასარგებლო ვიწროების შენარჩუნებით.
ის გეხმარებათ, დაწეროთ პატარა isFoo ფუნქციები, შეაერთოთ ისინი უფრო მდიდარ გაშვების დროის შემოწმებებად, დააზუსტოთ თვისებები უკვე ცნობილ მნიშვნელობებზე და შეინარჩუნოთ TypeScript-ის ვიწროება ბუნებრივი მართვის ნაკადში. საჭიროების შემთხვევაში გამოიყენეთ გაშვების საზღვრებზე, სქემაზე ორიენტირებული სამუშაო პროცესის გარეშე.
გაშვებისას უსაფრთხო 🛡️, კომპოზიციური 🧩 და ერგონომიული ✨ მძიმე სქემის სამუშაო პროცესის მიღების გარეშე.
- შექმენით და ხელახლა გამოიყენეთ ტიპიზირებული გუარდები
-
შეაერთეთ გუარდები
and,or,not,oneOf-ით - გამოიყენეთ
refineKeyშვილობილი თვისების დასაზუსტებლად, მშობლის ტიპის შენარჩუნებით - შეამოწმეთ ობიექტების სტრუქტურა და კოლექციები, როცა ეს სასარგებლოა
-
დაამუშავეთ ან დაადასტურეთ
unknownმნიშვნელობები დიდი სქემის ბიბლიოთეკის გარეშე
GitHub-ზე ნახვასაუკეთესო…
და თუ პროექტი მოგეწონათ, ⭐ ამ პატარა კატას ძალიან გაახარებს! 😸
მადლობა კითხვისთვის! 🤲


