Производное состояние и селекторы с типами
Пишите типизированные функции-селекторы для вычисляемого состояния
«Производное состояние и селекторы с типами» — бесплатный урок TypeScript Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения TypeScript Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс TypeScript Academy содержит 4 уроков всего.
Что такое производное состояние
Производное состояние — это состояние, вычисленное на основе другого состояния, например отфильтрованный список или сумма значений. Селекторы инкапсулируют это вычисление, и их можно мемоизировать для повышения производительности.
// Raw state
const users: User[] = [/* ... */];
// Derived state: active users only
const activeUsers = users.filter(u => u.isActive);Типизированные функции-селекторы
Пишите функции-селекторы с явными возвращаемыми типами, чтобы документировать вычисляемый результат и предотвращать расхождение типов.
import type { RootState } from "./store";
const selectActiveUsers = (state: RootState): User[] =>
state.users.filter((u) => u.isActive);
const selectUserCount = (state: RootState): number =>
state.users.length;reselect: мемоизированные селекторы
Библиотека reselect (используемая RTK) создаёт мемоизированные селекторы, которые пересчитываются только при изменении входных данных.
import { createSelector } from "reselect";
const selectActiveUsers = createSelector(
(state: RootState) => state.users,
(users) => users.filter((u) => u.isActive)
);
// Return type inferred: User[]Типизированные параметризованные селекторы
Селекторы-фабрики принимают аргументы и возвращают селектор — это удобно для поиска отдельных сущностей.
const selectUserById = (id: string) =>
createSelector(
(state: RootState) => state.users,
(users) => users.find((u) => u.id === id) ?? null
);
// Usage: const user = useAppSelector(selectUserById("123"));Селекторы Zustand
В Zustand передайте типизированный селектор в хук хранилища, чтобы читать только нужную часть состояния.
const activeUsers = useUserStore((s) => s.users.filter(u => u.isActive));
// Inferred type: User[]Производное состояние в React с useMemo
Для локального производного состояния используйте useMemo с правильными аннотациями типов, чтобы мемоизировать вычисляемые значения в компонентах.
const sortedUsers = useMemo(
(): User[] => [...users].sort((a, b) => a.name.localeCompare(b.name)),
[users]
);Композиция селекторов
Создавайте сложные селекторы, объединяя более простые: reselect обрабатывает мемоизацию по всей цепочке.
const selectActiveUserNames = createSelector(
selectActiveUsers,
(users) => users.map((u) => u.name)
); // string[]Типобезопасный Zustand с immer для производных обновлений
При вычислении производных обновлений используйте immer для изменения чернового состояния — TypeScript гарантирует, что изменяются только допустимые свойства.
const useStore = create<AppStore>()(immer((set) => ({
users: [],
activeCount: 0,
setUsers: (users) =>
set((draft) => {
draft.users = users;
draft.activeCount = users.filter((u) => u.isActive).length;
}),
})));Вывод типа возвращаемого значения селектора
TypeScript выводит возвращаемые типы из селекторов, но явные аннотации повышают читаемость и предотвращают случайное появление any в динамических выражениях.
// Inferred — may widen to any for complex expressions
const selectTotals = createSelector(
(s: RootState) => s.cart.items,
(items) => items.reduce((sum, i) => sum + i.price, 0) // inferred: number
);Тестирование селекторов
Селекторы являются чистыми функциями: тестируйте их, передавая имитацию состояния и проверяя тип и значение результата.
test("selectActiveUsers", () => {
const state = { users: [{ id: "1", isActive: true }, { id: "2", isActive: false }] } as RootState;
expect(selectActiveUsers(state)).toHaveLength(1);
});Итоги: типизированные селекторы
Типизированные селекторы: пишите функции, принимающие RootState, с явными возвращаемыми типами, используйте createSelector для мемоизации, объединяйте селекторы для сложных вычислений и тестируйте их как чистые функции.
Быстрая проверка
Какое преимущество даёт createSelector по сравнению с обычной функцией-селектором?
Чему Вы научились
Типизированные селекторы принимают RootState и возвращают производные значения с точной типизацией. Используйте createSelector для мемоизации, объединяйте селекторы для сложной логики и создавайте селекторы-фабрики для параметризованного поиска сущностей.
Часто задаваемые вопросы
Урок «Производное состояние и селекторы с типами» бесплатный?
Да — полный текст урока «Производное состояние и селекторы с типами» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс TypeScript Academy, подпишись на CoddyKit PRO. Курс TypeScript Academy содержит 4 уроков всего.
Чему я научусь в уроке «Производное состояние и селекторы с типами»?
Пишите типизированные функции-селекторы для вычисляемого состояния Ты практикуешь TypeScript Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать TypeScript Academy?
Предыдущий опыт не требуется. TypeScript Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Производное состояние и селекторы с типами»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке TypeScript Academy?
Да. Каждый урок TypeScript Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Типизация срезов и асинхронных действий Redux Toolkit
- Шаблоны типизации хранилищ Zustand
- XState: типизированные конечные автоматы
- Производное состояние и селекторы с типами