0Pricing
TypeScript Academy · Урок

Производное состояние и селекторы с типами

Пишите типизированные функции-селекторы для вычисляемого состояния

«Производное состояние и селекторы с типами» — бесплатный урок 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 — локальная установка не требуется.

Все уроки этого курса

  1. Типизация срезов и асинхронных действий Redux Toolkit
  2. Шаблоны типизации хранилищ Zustand
  3. XState: типизированные конечные автоматы
  4. Производное состояние и селекторы с типами
← Назад к TypeScript Academy