Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Як типізувати useCallback()?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)`useCallback` повертає **мемоізовану функцію**, тип якої залежить від її тіла - TypeScript автоматично виведе тип, якщо все оголошено явно. **Ключове:** не варто типізувати вручну, якщо TypeScript може вивести тип сам; коли тип важливий для сумісності з пропсами, використовуй generic у `useCallback<FnType>()`.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Базовий синтаксис ```javascript const callback = useCallback(() => { // ... }, []); ``` `useCallback` повертає **мемоізовану функцію**, тип якої залежить від її тіла. TypeScript автоматично виведе тип, якщо все оголошено явно. --- ## 1. Найпростіший варіант - автотипізація (рекомендується) TypeScript **сам виводить** тип функції, якщо параметри і значення, що повертається, вказані всередині: ```javascript const handleClick = useCallback((id: number) => { console.log(id); }, []); ``` Тип тут: ```javascript (id: number) => void ``` **Рекомендація:** не дублюй типізацію зовні, якщо TypeScript може вивести її сам. --- ## 2. Вказання типу явно (наприклад, для колбеків у props) Іноді потрібно, щоб сигнатура колбека збігалася з очікуваним типом з пропсів або інтерфейсу. ```javascript type OnSelect = (id: string) => void; const handleSelect: OnSelect = useCallback((id) => { console.log(id); }, []); ``` Або, щоб не писати зайвого: ```javascript const handleSelect = useCallback<OnSelect>((id) => { console.log(id); }, []); ``` > Вказуємо generic `<OnSelect>` прямо у `useCallback`. > Це змусить TypeScript строго перевіряти сигнатуру функції. --- ## 3. Повна типізація сигнатури всередині `useCallback` Якщо хочеш все явно в одному місці: ```javascript const handleChange = useCallback<(event: React.ChangeEvent<HTMLInputElement>) => void>( (event) => { console.log(event.target.value); }, [] ); ``` Тепер `handleChange` буде строго типізований як `ChangeEventHandler<HTMLInputElement>`. --- ## 4. Приклад зі значенням, що повертається ```javascript const compute = useCallback((a: number, b: number): number => { return a + b; }, []); ``` Тип: ```javascript (a: number, b: number) => number ``` TypeScript виведе тип автоматично - явно вказувати `useCallback<number>` не потрібно. --- ## 5. Типізація в парі з `React.FC` або пропсами Припустимо, у нас компонент, який приймає колбек у пропсах: ```javascript type Props = { onSave: (data: string) => void; }; function Form({ onSave }: Props) { const handleSubmit = useCallback(() => { onSave('data'); }, [onSave]); return <button onClick={handleSubmit}>Save</button>; } ``` Тут `handleSubmit` виведе тип `(event: React.MouseEvent<HTMLButtonElement>) => void` автоматично, якщо ви передасте його в `onClick`. --- ## 6. Використання з event-хендлерами React вже надає типи для подій: ```javascript const handleChange = useCallback( (e: React.ChangeEvent<HTMLInputElement>) => { console.log(e.target.value); }, [] ); ``` або з generic-підходом: ```javascript const handleClick = useCallback<React.MouseEventHandler<HTMLButtonElement>>( (e) => { e.preventDefault(); }, [] ); ``` > `React.MouseEventHandler<T>` = `(event: React.MouseEvent<T, MouseEvent>) => void` --- ## 7. Якщо потрібно типізувати generic-функцію ```javascript const identity = useCallback(<T,>(value: T): T => { return value; }, []); ``` Використання: ```javascript identity(123); // number identity('hello'); // string ``` Generic зберігається - `useCallback` коректно працює з `<T,>`. --- ## 8. Спільне використання з `useMemo` Якщо `useCallback` повертає складну функцію, можна явно типізувати її сигнатуру і передати в мемоізацію: ```javascript type FetchFn = (url: string) => Promise<Response>; const fetchData = useCallback<FetchFn>(async (url) => { const res = await fetch(url); return res; }, []); ``` --- ## 9. Часті помилки #### Помилка 1: не вказувати залежності ```javascript const handle = useCallback(() => console.log(value), []); ``` Якщо `value` змінюється - функція буде "зависати" на старому значенні. Виправ: ```javascript const handle = useCallback(() => console.log(value), [value]); ``` --- #### Помилка 2: неправильний generic-порядок ```javascript useCallback<void, [string]>((value) => {}, []); // так не працює ``` Такий синтаксис не працює. `useCallback` приймає **один generic** - тип функції цілком: ```javascript useCallback<(value: string) => void>((value) => {}, []); ``` --- ## Підсумок | Сценарій | Як типізувати | |---|---| | Проста функція | Автоматично (TS сам виведе) | | Визначена сигнатура | `useCallback<FnType>(...)` | | Callback з пропсів | `const cb: Props["onChange"] = useCallback(...)` | | Події React | `useCallback<React.ChangeEventHandler<HTMLInputElement>>` | | Generic функція | `useCallback<<T,>(x: T) => T>` | --- ## Рекомендації - **Не типізуй вручну**, якщо TypeScript може вивести тип. - Якщо тип важливий для сумісності з пропсами - **використовуй generic у** `useCallback<>()`. - Для подій - використовуй вбудовані типи з `React.*EventHandler`. - Для generic-функцій - не забувай про кому `<T,>`.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.