Использовал ли ты mapped types в TypeScript
Что проверяют
Использовали ли вы продвинутые типы на практике или знаете их по документации. Вопрос звучит как «да или нет», но ждут пример из проекта. Следом обычно просят написать mapped type на месте, часто с переименованием ключей через as.
Как отвечать
Сначала коротко про механику. Mapped type проходит по объединению ключей и строит новый объектный тип: { [K in keyof T]: T[K] }. На этой основе покажите, что знаете:
- модификаторы:
?иreadonlyможно добавить или снять через-?и-readonly. Так устроены встроенныеPartial,Required,Readonly; - переименование ключей через
as(с TypeScript 4.1): шаблонный типon${Capitalize<K & string>}генерирует имена обработчиков, аas neverотфильтровывает ненужные ключи; - гомоморфность: mapped type по
keyof Tсохраняет модификаторы исходных свойств, а применённый к массиву или кортежу возвращает массив или кортеж; - связь со стандартной библиотекой:
RecordиPickтоже mapped types,Omitсобран изPickиExclude.
Дальше пример из своей работы. Хорошо звучат реальные задачи: тип ошибок формы { [K in keyof FormValues]?: string }, который не даст опечататься в имени поля, DTO для PATCH-запроса из модели сущности, типизированный набор обработчиков событий, конфиг, где каждому ключу соответствует свой тип значения. Назовите, какую ошибку это поймало на этапе компиляции.
Если сами mapped types не писали, скажите честно: пользовались Partial, Pick, Record и понимаете, как они устроены внутри. Такой ответ с правильной механикой лучше выдуманного проекта.
Где спотыкаются
Считают, что Partial работает рекурсивно. Он делает необязательным только первый уровень, DeepPartial пишут сами, и в нём отдельно обрабатывают массивы, функции и Date.
Забывают, что keyof может вернуть не только string, но и number и symbol. Поэтому Capitalize<K> без K & string не компилируется.
Путают mapped type с индексной сигнатурой { [key: string]: T }. Сигнатура разрешает любые ключи, mapped type перечисляет конкретные. К тому же mapped type объявляется только через type, в interface его не записать.