Выбор ответа Middle Условные и mapped-типы обновлено

keyof в шаблонной строке

Вопрос

Почему Capitalize<K> даёт ошибку?

type Getters<T> = {
  [K in keyof T as `get${Capitalize<K>}`]: () => T[K];
};

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: keyof T может дать number и symbol, а Capitalize ждёт строку. Ключи объекта в TypeScript это string number symbol, и для дженерика T компилятор не знает, какие окажутся.

Варианты ответа

  1. Нужно писать K in T, а не K in keyof T, иначе ключ теряет тип
  2. Capitalize не работает внутри mapped-типов, только в обычных алиасах
  3. keyof T может дать number и symbol, а Capitalize ждёт строкуправильный ответ
  4. Внутри as нельзя использовать шаблонные строки вроде `get${...}`

Разбор

Ключи объекта в TypeScript это string | number | symbol, и для дженерика T компилятор не знает, какие окажутся. Capitalize<S extends string> принимает только строки. Решение: Capitalize<string & K> или K & string, тогда числовые и символьные ключи отфильтруются.

Capitalize и шаблоны внутри as работают, это штатный способ переименовывать ключи. K in T для объекта не имеет смысла: перебирают ключи.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.