логотип PurpleSchool

Возврат undefined из функции

30 сентября 2022 г.
1 270 просмотров
фото команды
Автор

Антон

Давайте рассмотрим пример следующей функции:

async function getUser(id: number): Promise<User> {
    // получение пользователя из базы, 
    // если не находит, то возвращает undefined
    return db.query(/*...*/);
}

Если у вас не стоит strict режим или поставлена опция "strictNullChecks": false в tsconfig.json ошибки не будет.

Чем это плохо? Мы не очевидно получаем поведение, где мы передаём id и ожидаем пользователя, а на самом деле можем получить undefined. В результате надо не забыть сделать соответствующую проверку. Давайте сделаем это очевиднее!

Разберём отличия

Прежде чем переходить к решению, давайте разберём, чем отливается null от undefined.

  • null
    • ключевое слово языка, которое отображается отсутствие того или иного объекта. Его мы не можем получить случайно, это значение умышленно поставлено.
  • undefined
    • обозначает отсутствие значение в принципе и его мы можем получить случайно.

Мы можем получить undefined например:

  • Не задав переменную.
  • Обратившись к несуществующему свойству объекта.
  • Не передав аргумент в функцию.

Исходя из этого, полагаться на то, что это значение осмысленное - плохо. Если мы явно хотим обозначить отсутствие значение следует использовать null. Как тогда меняется наша функция?

Подход с null

Давайте сделаем api нашей функции явным:

async function getUser(id: number): Promise<User | null> {
    const user: User = db.query(/*...*/);
    if(!user) {
        return null;
    }
    return user;
}

Теперь мы явно обозначаем пользователю этой функции, что мы можем найти или не найти пользователя, обязуя его делать проверку на null явно в своём коде, убирая не очевидное поведение.

Плохой подход с exception

Есть ещё более плохой подход, где у нас функция при не нахождении пользователя кидает ошибку:

async function getUser(id: number): Promise<User> {
    const user: User = db.query(/*...*/);
    if (!user) {
        throw new Error('Пользователь не найден');
    }
    return user;
}

Тут управление потоком исполнение становится не линейным и не очевидным и нужно не забыть всё обложить try / catch. Так точно делать не нужно, так как мы получаем вместо последовательного кода прыжки по обработчикам ошибок.

изображение курса

TypeScript с нуля

Антон Ларичев
иконка часов18 часов лекций
иконка зведочки рейтинга4.8
TypeScript с нуля