Пошук уроків, статей та іншого контенту
Розберіться з null та undefined, їх відмінностями й налаштуванням суворої перевірки цих значень.
undefined і nullundefined та null позначають відсутність значення, але використовуються в різних ситуаціях.
undefined означає, що значення не було визначене або не було передане.
null означає навмисно порожнє значення.
let notAssigned: string | undefined;
console.log(notAssigned); // undefined
let selectedUser: string | null = null;
console.log(selectedUser); // nullУ першому випадку змінна оголошена, але їй не присвоєно значення. У другому випадку ми явно вказали, що користувач не вибраний.
undefinedЗначення undefined часто з’являється автоматично:
let message: string;
console.log(message); // undefinedТакож його повертають функції, які не мають оператора return:
function logMessage(message: string): void {
console.log(message);
}
const result = logMessage("Привіт");
console.log(result); // undefinedМетод масиву find також може повернути undefined, якщо елемент не знайдено:
const numbers = [10, 20, 30];
const foundNumber = numbers.find((number) => number > 100);
console.log(foundNumber); // undefinedТому тип результату find може бути number | undefined.
nullnull зазвичай використовують, коли потрібно явно повідомити: значення відсутнє.
Наприклад, змінна може містити ім’я користувача або null, якщо користувач ще не авторизувався:
let currentUser: string | null = null;
currentUser = "Олена";
currentUser = null;Тип string | null називається об’єднанням типів. Він означає, що змінна може містити або рядок, або null.
Без | null TypeScript не дозволить присвоїти null змінній типу string, якщо увімкнено сувору перевірку.
null та undefinedУ JavaScript обидва значення є окремими:
console.log(null === undefined); // false
console.log(null == undefined); // trueОператор === перевіряє і значення, і тип, тому null та undefined не дорівнюють одне одному.
Оператор == виконує нестроге порівняння та вважає їх рівними. У TypeScript і сучасному JavaScript зазвичай краще використовувати === та !==, щоб уникати неочікуваного перетворення типів.
const value: string | null | undefined = null;
if (value === null) {
console.log("Значення дорівнює null");
}
if (value === undefined) {
console.log("Значення дорівнює undefined");
}Якщо потрібно перевірити обидва значення одразу, можна використати == null, але цей запис має бути свідомим:
function printValue(value: string | null | undefined): void {
if (value == null) {
console.log("Значення відсутнє");
return;
}
console.log(value);
}Умова value == null спрацює і для null, і для undefined.
strictNullChecksОсновна налаштування TypeScript для роботи з null та undefined — strictNullChecks.
Її можна увімкнути у файлі tsconfig.json:
{
"compilerOptions": {
"strictNullChecks": true
}
}Коли strictNullChecks увімкнено:
null і undefined є окремими типами;
їх не можна присвоювати звичайним типам без явного зазначення;
TypeScript змушує перевіряти можливу відсутність значення.
let name: string = "Ірина";
// Помилка TypeScript:
// Type 'null' is not assignable to type 'string'
name = null;Щоб дозволити null, потрібно додати його до типу:
let name: string | null = null;
name = "Ірина";Те саме стосується undefined:
let age: number | undefined;
age = 25;
age = undefined;Параметр без значення за замовчуванням також може бути undefined, якщо його зробити необов’язковим:
function greet(name?: string): string {
if (name === undefined) {
return "Привіт, незнайомцю!";
}
return `Привіт, ${name}!`;
}
console.log(greet("Андрій"));
console.log(greet());Параметр name?: string фактично має тип string | undefined.
Якщо змінна може бути null або undefined, спочатку потрібно перевірити її значення.
function getNameLength(name: string | null): number {
if (name === null) {
return 0;
}
return name.length;
}
console.log(getNameLength("Марія")); // 5
console.log(getNameLength(null)); // 0Після перевірки TypeScript звужує тип змінної. Усередині другого блоку name уже має тип string, тому властивість length можна безпечно використовувати.
Для перевірки і null, і undefined можна застосувати перевірку на істинність:
function printName(name: string | null | undefined): void {
if (!name) {
console.log("Ім’я відсутнє");
return;
}
console.log(`Ім’я: ${name}`);
}Але така перевірка вважає відсутнім не лише null та undefined, а й порожній рядок, число 0 та false. Якщо потрібно перевіряти тільки null і undefined, використовуйте явне порівняння:
function printText(text: string | null | undefined): void {
if (text === null || text === undefined) {
console.log("Текст відсутній");
return;
}
console.log(text);
}Оператор ?? повертає значення праворуч, якщо ліворуч знаходиться null або undefined.
const savedName: string | null = null;
const displayName = savedName ?? "Гість";
console.log(displayName); // ГістьЦе відрізняється від оператора ||. Він замінює також інші «хибні» значення, наприклад порожній рядок або 0:
const count = 0;
console.log(count || 10); // 10
console.log(count ?? 10); // 0Якщо потрібно замінити лише null та undefined, використовуйте ??.
Якщо об’єкт може бути null або undefined, для безпечного доступу до його властивостей можна використовувати оператор ?..
type User = {
name: string;
};
function getUserName(user: User | null): string {
return user?.name ?? "Невідомий користувач";
}
console.log(getUserName({ name: "Софія" }));
console.log(getUserName(null));Вираз user?.name поверне undefined, якщо user дорівнює null або undefined, замість помилки під час виконання.
type Profile = {
username: string;
email: string | null;
};
function getEmail(profile: Profile | undefined): string {
if (profile === undefined) {
return "Профіль не знайдено";
}
return profile.email ?? "Електронну пошту не вказано";
}
const existingProfile: Profile = {
username: "olena",
email: null
};
const missingProfile: Profile | undefined = undefined;
console.log(getEmail(existingProfile)); // Електронну пошту не вказано
console.log(getEmail(missingProfile)); // Профіль не знайденоТут:
profile | undefined означає, що профіль може не бути знайдений;
email: string | null означає, що профіль існує, але пошта може бути навмисно не вказана;
?? задає текст за замовчуванням для null;
перевірка profile === undefined захищає від використання відсутнього об’єкта.
null або undefined звичайному типуlet title: string = "Новина";
// Помилка при увімкненому strictNullChecks:
// title = null;Якщо значення справді може бути відсутнім, зазначте це в типі:
let title: string | null = null;function getLength(text: string | undefined): number {
// Помилка: text може бути undefined
// return text.length;
if (text === undefined) {
return 0;
}
return text.length;
}TypeScript попереджає про таку помилку, щоб програма не завершилася з помилкою під час виконання.
|| та ??const username = "";
console.log(username || "Гість"); // Гість
console.log(username ?? "Гість"); // порожній рядок|| перевіряє «хибність» значення, а ?? — тільки null та undefined.
const value: string | null | undefined = null;
if (value === null || value === undefined) {
console.log("Значення відсутнє");
}Такий запис однозначно показує, які саме значення перевіряються. == null також працює, але його варто застосовувати лише тоді, коли ви свідомо хочете перевірити обидва значення.
undefined зазвичай означає, що значення не визначене або не передане.
null використовують для явного позначення відсутності значення.
null і undefined — різні типи та різні значення.
strictNullChecks змушує явно вказувати можливість null або undefined.
Для цього використовують об’єднання типів: string | null або number | undefined.
Перед доступом до властивостей потенційно відсутнього значення його потрібно перевірити.
Оператор ?? задає значення за замовчуванням лише для null та undefined.
Оператор ?. допомагає безпечно звертатися до властивостей об’єкта, який може бути відсутнім.