Що таке "type guard"?
Що таке Type Guard
Type Guard - це логічний вираз або функція, яка допомагає TypeScript уточнити тип змінної в певній гілці коду.
Простіше кажучи: Type Guard - це спосіб "сказати компілятору, хто я насправді".
Приклад без type guard
function printId(id: string | number) {
console.log(id.toUpperCase()); // Помилка - id може бути number
}TypeScript не знає, id - це string чи number.
З Type Guard
function printId(id: string | number) {
if (typeof id === "string") {
// тут id: string
console.log(id.toUpperCase());
} else {
// тут id: number
console.log(id.toFixed(2));
}
}Перевірка typeof id === "string" - це вбудований type guard.
TS автоматично звужує тип усередині кожної гілки.
Основні види Type Guards
| Вид | Перевірка | Приклад |
|---|---|---|
typeof | для примітивів | typeof value === "string" |
instanceof | для класів і конструкторів | value instanceof Date |
in | перевірка існування властивості | "prop" in obj |
Користувацька функція v is Type | кастомний type guard | isString(value): value is string |
1. Type guard через typeof
Використовується для перевірки примітивних типів:
"string", "number", "boolean", "symbol", "undefined", "object", "function".
function process(val: string | number | boolean) {
if (typeof val === "string") {
// val: string
console.log(val.toUpperCase());
} else if (typeof val === "number") {
// val: number
console.log(val.toFixed(2));
} else {
// val: boolean
console.log(val ? "true" : "false");
}
}2. Type guard через instanceof
Використовується для перевірки, чи був об'єкт створений конкретним класом або конструктором.
function logDate(value: Date | string) {
if (value instanceof Date) {
// value: Date
console.log(value.toISOString());
} else {
// value: string
console.log(value.toUpperCase());
}
}3. Type guard через оператор in
Перевіряє, чи є у об'єкта конкретна властивість, і TS звужує тип залежно від результату.
type Car = { drive: () => void };
type Boat = { sail: () => void };
function move(vehicle: Car | Boat) {
if ("drive" in vehicle) {
// vehicle: Car
vehicle.drive();
} else {
// vehicle: Boat
vehicle.sail();
}
}4. Користувацькі type guards (v is Type)
Можна оголосити свою функцію, яка повертає логічне значення і вказує TypeScript,
що якщо вона повернула true - значить аргумент має конкретний тип.
Синтаксис:
function isDog(pet: Animal): pet is Dog {
return (pet as Dog).bark !== undefined;
}Приклад використання:
type Dog = { bark: () => void };
type Cat = { meow: () => void };
function isDog(animal: Dog | Cat): animal is Dog {
return (animal as Dog).bark !== undefined;
}
function makeSound(animal: Dog | Cat) {
if (isDog(animal)) {
animal.bark(); // animal: Dog
} else {
animal.meow(); // animal: Cat
}
}Тут вираз
animal is Dogкаже TS: "Якщо функція повернула true - далі animal точно Dog".
Type guards і narrowing
Type guards - це основний механізм, через який відбувається type narrowing (звуження типів). Фактично:
Type guard → запускає narrowing.
Просунутий приклад
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function isCircle(s: Shape): s is { kind: "circle"; radius: number } {
return s.kind === "circle";
}
function area(shape: Shape) {
if (isCircle(shape)) {
// shape: circle
return Math.PI * shape.radius ** 2;
} else {
// shape: square
return shape.side ** 2;
}
}Реальні кейси застосування
- Перевірка даних після парсингу JSON
- Перевірка API-відповідей (runtime type checking)
- Фільтрація масивів за типами
- Робота з union типами і discriminated unions
- Звуження при роботі з
unknownіany
Приклад: фільтрація масиву
function isString(value: unknown): value is string {
return typeof value === "string";
}
const mixed = [1, "a", 2, "b", true];
const strings = mixed.filter(isString);
// strings: string[]Підсумок
| Термін | Визначення |
|---|---|
| Type Guard | Перевірка, яка допомагає TypeScript визначити конкретний тип значення |
| Мета | Звуження (narrowing) об'єднаних або невідомих типів |
| Види | typeof, instanceof, in, користувацькі (value is Type) |
| Головна користь | Безпечний доступ до властивостей і методів конкретних типів без приведень (as) |
Простіше кажучи:
Type Guard - це "охоронець", який стоїть на шляху union-типу і каже TypeScript: «Не хвилюйся, я перевірив - тепер точно знаємо, хто це».
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.