Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як типізувати useState, коли початкове значення null чи порожній масив?

TypeScript виводить тип стану з початкового значення, і найчастіше явний тип не потрібен:

const [count, setCount] = useState(0);          // number
const [name, setName] = useState('');           // string
const [open, setOpen] = useState(false);        // boolean

Коли виведення не спрацьовує:

1. Початкове null - значення з'явиться пізніше:

type User = { id: number; name: string };

const [user, setUser] = useState<User | null>(null);

if (user) {
  user.name;   // після перевірки - User
}

Без явного типу useState(null) дасть тип null, і setUser(data) не скомпілюється.

2. Порожній масив:

const [items, setItems] = useState<Product[]>([]);

Без параметра useState([]) дає never[] - у такий масив нічого не додати.

3. Обмежений набір значень (union):

type Status = 'idle' | 'loading' | 'success' | 'error';
const [status, setStatus] = useState<Status>('idle');

Без явного типу стан стане string, і setStatus('sucess') з помилкою пройде.

Стани, що залежать один від одного, краще поєднати в один з дискримінованим union - тоді неможливі комбінації не скомпілюються:

type RequestState =
  | { status: 'loading' }
  | { status: 'success'; data: User[] }
  | { status: 'error'; error: string };

const [state, setState] = useState<RequestState>({ status: 'loading' });

if (state.status === 'success') {
  state.data;   // доступно лише тут
}

Окремі isLoading, error, data дозволяють стан «завантажується, але з помилкою й даними», а union - ні.

Функція оновлення типізується автоматично: setCount((c) => c + 1) знає, що c - число.

Лінива ініціалізація теж виводить тип з результату: useState(() => readFromStorage()).

Пастка: useState<User>({} as User) - «обіцянка» компілятору, що порожній об'єкт - повноцінний User. Помилки звернення до відсутніх полів з'являться під час виконання, а не компіляції. Чесніше User | null.

Докладніше в документації: TypeScript у React: useState

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання