Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Оператор typeof у JavaScript». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`typeof` у JavaScript працює під час виконання (runtime) і повертає рядок з назвою типу значення: `"number"`, `"string"`, `"boolean"`, `"undefined"`, `"object"`, `"function"`, `"symbol"`, `"bigint"`.** Масиви і `null` дають `"object"` (для `null` це історична помилка мови), а функції мають окреме значення `"function"`. Для неоголошеної змінної `typeof` не кидає `ReferenceError`, а безпечно повертає `"undefined"`. У TypeScript той самий запис у позиції типу працює зовсім інакше: він виконується на етапі компіляції і повертає не рядок, а тип. ```javascript typeof [1, 2, 3]; // "object" typeof null; // "object" typeof function(){} // "function" ``` **Ключове:** у JS `typeof` це runtime-оператор, що віддає рядок; у TS це compile-time оператор, що віддає тип.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**`typeof` це оператор, який під час виконання програми повертає рядок з описом типу значення.** У TypeScript ключове слово `typeof` у позиції типу означає інше: воно на етапі компіляції витягує тип змінної, функції або класу. ## Теорія ### TL;DR - У JavaScript `typeof` працює в runtime і повертає **рядок**, а не сам тип. - Можливі результати: `"number"`, `"string"`, `"boolean"`, `"undefined"`, `"object"`, `"function"`, `"symbol"`, `"bigint"`. - `typeof null` дає `"object"`, це відома історична помилка мови. - Масиви технічно є об'єктами, тому `typeof []` теж дає `"object"`. - `typeof` для неоголошеної змінної не кидає помилку: безпечний спосіб перевірити її наявність. - У TypeScript `typeof` у позиції типу працює в compile-time і повертає тип. ### Швидкий приклад ```javascript console.log(typeof 42); // "number" console.log(typeof 'hello'); // "string" console.log(typeof true); // "boolean" console.log(typeof undefined); // "undefined" console.log(typeof { a: 1 }); // "object" console.log(typeof [1, 2, 3]); // "object" (масиви це об'єкти!) console.log(typeof null); // "object" (історична помилка мови) console.log(typeof function(){}); // "function" ``` > Оператор повертає **рядок**, а не сам тип. ### Особливості результатів typeof | Ситуація | Результат | Коментар | | --- | --- | --- | | `typeof x` (якщо `x` не оголошена) | `"undefined"` | Не кидає помилку, це безпечно | | `typeof null` | `"object"` | Історична помилка в JS | | `typeof []` | `"object"` | Масиви технічно є об'єктами | | `typeof function() {}` | `"function"` | Спеціальний підтип об'єкта | Головне, що варто запам'ятати: `typeof` не вміє відрізнити масив від звичайного об'єкта чи від `null`. Для масива використовують `Array.isArray(x)`, а `null` перевіряють прямим порівнянням `x === null`. ### Безпечна перевірка наявності змінної ```javascript if (typeof user === 'undefined') { console.log('user is not defined'); } ``` Тут `typeof` дозволяє перевірити наявність змінної **без помилки**, навіть якщо вона взагалі не оголошена. Будь-яке інше звертання до неоголошеного ідентифікатора одразу дало б `ReferenceError`. ### typeof у TypeScript А ось тепер головна відмінність. > У **TypeScript** `typeof` це **оператор, що працює з типами на етапі компіляції (compile-time)**, і він повертає **тип**, а не рядок. Тобто він **не обчислює значення**, а **бере тип змінної або виразу**, щоб цей тип можна було використати в анотаціях. ```typescript const user = { name: 'Tim', age: 30 }; // беремо тип об'єкта user type UserType = typeof user; // еквівалентно: type UserType = { name: string; age: number; }; ``` > На відміну від JavaScript, `typeof` тут **не виконує код**, а просто **витягує тип** змінної, функції або класу. ### typeof разом з ReturnType ```typescript function makeUser() { return { name: 'Alice', active: true }; } type User = ReturnType<typeof makeUser>; // User = { name: string; active: boolean } ``` > Тут `typeof makeUser` дає **тип функції**, а `ReturnType<...>` дає тип значення, яке ця функція повертає. ### Ключові відмінності JS і TS | Особливість | `typeof` у JavaScript | `typeof` у TypeScript | | --- | --- | --- | | Коли працює | Під час виконання (runtime) | Під час компіляції (compile-time) | | Що повертає | Рядок з типом (`"number"`, `"object"`, ...) | Тип змінної, функції або об'єкта | | Чи можна вживати в умовах | Так | Ні, працює лише в типах | | Приклад | `typeof x === 'string'` | `type T = typeof x` | | Якщо `x` не оголошена | Помилки немає | Помилка компіляції | ### Приклад для контрасту ```javascript // JavaScript let a = 10; console.log(typeof a); // "number" ``` ```typescript // TypeScript let a = 10; type AType = typeof a; // AType = number ``` > Перший повертає рядок **під час виконання**, другий створює **тип** на етапі компіляції. ### Типові помилки - **Очікувати `"array"` від `typeof []`.** Такого результату не існує, масив це об'єкт. Використовуйте `Array.isArray(value)`. - **Покладатися на `typeof value === 'object'` для перевірки об'єкта.** `null` теж пройде цю перевірку. Правильно: `value !== null && typeof value === 'object'`. - **Плутати рядок і тип.** `typeof x` у JS це завжди рядок, тому `typeof x === Number` ніколи не буде істиною, треба `typeof x === 'number'`. - **Думати, що `typeof` у TS перевіряє щось у рантаймі.** У позиції типу він зникає після компіляції і не впливає на згенерований JavaScript. - **Забувати про `typeof` як про єдиний безпечний спосіб торкнутися неоголошеної змінної.** Перевірка `if (user === undefined)` кине `ReferenceError`, а `if (typeof user === 'undefined')` ні.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.