Typed custom hooks: constraints и infer для строгих конфигов
Typed custom hooks: constraints и infer для строгих конфигов Часто вижу, как custom hooks принимают конфиги, где TypeScript выводит mode: string вместо 'edit' | 'view', а permissions — string[] вместо конкретных литералов. В production это ведет к потере автодополнения и багам на стороне потребителей. Constraints: фиксируем рамки Используй extends уже на уровне дженериков хука, чтобы сузить допустимые типы. Без него TS выводит широкие типы, с ним — точные литералы, если исходные данные переданы с as const. function useFeature<M extends string, P extends string[]>(config: { mode: M; permissions: P; }) { // TS: M, P как литералы } Infer: выводим сложные зависимости Когда конфиг содержит вложенные коллбэки или динамические ключи, infer в условных типах автоматически извлекает нужные типы из переданного объекта. Это спасает от ручного аннотирования. type ConfigResult<T> = T extends { mode: infer M; permissions: infer P } ? { mode: M; permissions: P } : never; Типичная ошибка: забытый as const Без as const TS выведет string, а не литералы. А если конфиг приходит из API — этот подход бесполезен. Зато для статически заданных конфигов в хуках (фичи, A/B-тесты, permission guards) это чистый профит: типы не протекают, код самодокументируется. Вывод: Constraints с extends и вывод через infer дают строгую типизацию factory-функций и конфигурационных объектов без потери читаемости и с проверками на уровне компиляции.