Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Як типізувати useMemo()?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)Тип для **`useMemo()`** майже завжди можна **не вказувати** - TypeScript виведе його сам. **Ключове:** якщо ти повертаєш `null`, складні структури або `Map`, використовуй generic: `useMemo<Type>()`.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення```javascript // Без типу - TS виведе (User | null) const user = useMemo<User | null>(() => { if (!isLoggedIn) return null; return { id: 1, name: "Alex" }; }, [isLoggedIn]); ``` Використовуємо generic: ```javascript useMemo<Type>(() => value, deps); ``` --- ## 4. Приклад з масивами ```javascript const filtered = useMemo(() => data.filter(x => x.active), [data]); // TS виведе тип як (typeof data)[] ``` Якщо потрібно уточнити: ```javascript const filtered = useMemo<ItemType[]>(() => data.filter(...), [data]); ``` --- ## 5. Приклад з об'єктами і union-типами ```javascript type State = { status: "ok"; data: number[] } | { status: "error"; error: string }; const state = useMemo<State>(() => { try { return { status: "ok", data: [1, 2, 3] }; } catch { return { status: "error", error: "Oops" }; } }, []); ``` Тепер `state.status` перевіряється через `switch` без помилок. --- ## 6. useMemo + функції Якщо ти кешуєш **функцію**, можна типізувати її сигнатуру: ```javascript const getById = useMemo<((id: number) => Item | undefined)>(() => { return (id) => items.find(x => x.id === id); }, [items]); const item = getById(5); ``` > Альтернатива - `useCallback`, якщо ти кешуєш саме колбек. --- ## 7. Приклад з `Map`, `Set` і складними структурами ```javascript const map = useMemo<Map<string, number>>(() => new Map(), []); map.set("a", 1); ``` > Без явного типу TS іноді виведе `Map<any, any>`. --- ## 8. Якщо `useMemo` повертає `null` у деяких гілках ```javascript const element = useMemo<JSX.Element | null>(() => { if (!visible) return null; return <Chart data={data} />; }, [visible, data]); ``` Тепер TS знає, що `element` може бути `null`. --- ## 9. Комбіновані приклади ```javascript const config = useMemo<{ url: string; method: "GET" | "POST" }>( () => ({ url: `/api/${id}`, method: "GET" }), [id] ); const complex = useMemo< { title: string; tags: string[] } | null >(() => (ready ? { title: "Hello", tags } : null), [ready, tags]); ``` --- ## 10. Загальні поради | Сценарій | Типізація | |---|---| | Прості значення | Не вказуй - TS виведе сам | | Масиви, об'єкти | Можна явно `useMemo<T[]>(...)` або `useMemo<Record<string, T>>()` | | Union-типи (`null`, `undefined`) | Вкажи `<T | | `Map`, `Set`, `Date` | Вкажи `<Map<K, V>>`, `<Set<T>>`, `<Date>` | | Функції | Або `useCallback`, або `useMemo<FnType>(...)` | --- ## 11. Внутрішній тип `useMemo` ```javascript function useMemo<T>(factory: () => T, deps: DependencyList): T; ``` Тобто `useMemo` приймає **функцію, що повертає T**, і повертає `T`. --- ## Підсумок | Що типізувати | Як | |---|---| | Числа, рядки, булеві | `useMemo(() => ..., [...])` - авто | | Об'єкти / масиви | `useMemo<T>(() => ..., [...])` | | Nullable / optional | `useMemo<T | | Map / Set | `useMemo<Map<K, V>>(() => ..., [...])` | | Функції | `useMemo<FnType>(() => ..., [...])` | --- > **Головне:** > > - Тип можна майже завжди **не вказувати** - TS сам виведе. > - Але якщо повертаєш `null`, складні структури або `Map` - > використовуй generic: `useMemo<Type>()`. > - Не плутай `useMemo` (значення) і `useCallback` (функція).Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.