Narrowing არის ის, თუ როგორ აკეთებს TypeScript ფართო ტიპის (როგორიცაა union) უფრო კონკრეტულ ტიპებად კოდის ტოტში, runtime checks-ის საფუძველზე. კომპილერი აკონტროლებს control flow-ს და აახლებს ტიპს შესაბამისად.
ts
function process(x: string | number) {
if (typeof x === "string") {
x.toUpperCase(); // ✅ here x is narrowed to string
} else {
x.toFixed(2); // ✅ here x must be number
}
}
narrowing-ის ხელსაწყოები
ts
typeof x === "string" // typeof guard — for primitives
x instanceof Date // instanceof — for classes
"role" in obj // in operator — property existence
Array.isArray(x) // built-in guards
if (x) { ... } // truthiness narrows out null/undefined/0/""
if (x === null) { ... } // equality narrowing
Discriminated unions სწორად ვიწროვდება
ts
type Shape =
| { kind: "circle"; r: number }
| { kind: "square"; side: number };
function area(s: Shape) {
switch (s.kind) { // the discriminant
case "circle": return Math.PI * s.r ** 2; // s is the circle variant
case "square": return s.side ** 2; // s is the square variant
}
}
საზიარო literal field-ის (kind) შემოწმება ზუსტად იტყობინება კომპილერს, რომელი variant გაქვთ, რითაც გამოჯანმჯენებთ ამ variant-ის properties-ებს.
Custom guards აფართოებენ narrowing-ს
ts
function isUser(x: unknown): x is User { return !!x && typeof (x as any).name === "string"; }
რატომ არის ეს მნიშვნელოვანი
Narrowing არის ის, რაც union types-ებს გამოყენებადს ხდის — ეს საშუალებას გაძლევთ უსაფრთხოდ მივიდეთ ტიპ-სპეციფიკურ წევრებთან მხოლოდ მას შემდეგ, რაც დაამტკიცებთ ტიპს, runtime checks-ებს compile-time გარანტიებად გარდაქმნით.
ეს ყოველდღიური მექანიზმია string | number, T | null და tagged state-ის სამკურნალოდ.
