void - функція нічого корисного не повертає; результат не слід використовувати:
function log(message: string): void {
console.log(message);
}
Особливість: тип функції з void, наприклад () => void для колбеку, дозволяє передати функцію, що щось повертає. Результат просто ігнорується:
const ids: number[] = [];
[1, 2].forEach((n) => ids.push(n)); // push повертає number, але forEach очікує () => void - ок
Це навмисно: інакше багато звичайних колбеків довелося б обгортати.
undefined як тип повернення - функція явно повертає undefined, і результат можна використовувати як значення. З TS 5.1 функцію з типом undefined можна не закінчувати return.
never - функція ніколи не повертає керування:
function fail(message: string): never {
throw new Error(message);
}
function loop(): never {
while (true) {}
}
Після виклику такої функції код недосяжний, і TypeScript це враховує при звуженні:
const user = findUser(id) ?? fail('Користувача не знайдено'); // user: User, без undefined
never також - порожній тип: значення такого типу не існує. Тому його використовують для перевірки вичерпності (const _exhaustive: never = value) і він зникає з об'єднань: string | never - це string.
unknown - функція повертає щось, але тип невідомий: викликач має перевірити перед використанням. Правильний тип для JSON.parse, результатів сторонніх бібліотек без типів, catch (error).
Підсумок:
| Тип | Значення |
|---|---|
void |
«результат не використовувати» |
undefined |
«повертає саме undefined» |
never |
«не повертає взагалі» (виняток, нескінченний цикл, вихід з процесу) |
unknown |
«повертає щось, перевір перед використанням» |
Пастка з асинхронністю: async функція, що нічого не повертає, має тип Promise<void>, а не void. Передача її туди, де очікується () => void (обробник події), дозволена, але відхилений проміс ніхто не обробить - лінтер no-misused-promises це помічає.