Задать вопрос
@bzotsss

TS — почему строка обрабатывается по разному в варианте с дженериком и просто строкой в mapped types?

Всем привет ! не могу понять почему
MappedGenericStringTypeTest

Не работает так же как
MappedStringType

Дженерик просто принимает строку в MappedType и всё ... Но на выходе MappedStringType и MappedGenericStringTypeTest абсолютно разные ... Хотя и то и то по факту принимает строку ...
MappedStringType показывает что это обьект с кучей полей и методов для типа String и это мне понятно . Но почему MappedGenericStringTypeTest показывает что это просто строка литерал - "reviewsHistory_hz" мне не понятно ... Почему в MappedGenericStringTypeTest нету такого же миллона других полей и методов ... ? Как будто дженерик по другому вообще воспринял эту строку ... Вопрос почему?

ВОТ КОД

type MappedStringType = {
  [Key in keyof "reviewsHistory_hz"]: any;
};

type MappedGenericStringType<T extends string> = {
  [K in keyof T]: any;
};

type MappedGenericStringTypeTest = MappedGenericStringType<"reviewsHistory_hz">;
  • Вопрос задан
  • 24 просмотра
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 1
Alexandroppolus
@Alexandroppolus
кодир
Если кратко - "потому что так мир устроен".

{[K in keyof T]: ...} - это специальный особый паттерн, где ты итерируешься по ключам "локального типа" внутри генерика (аналог локальной переменной внутри функции). Важен тот факт, что тип именно локальный - либо параметр генерика, либо что-то, извлеченное с помощью infer.

В этом случае, во первых, игнорируется обработка примитивных типов, во вторых, если в T окажется массив или кортеж (если убрать ограничение на строку), то результат будет аналогичным массивом/кортежем той же конструкции, в третьих, если в T передать объединение типов, то происходит их дистрибуция, аналогичная этой, когда каждый элемент в объединении обрабатывается отдельно.

Если чуть изменить MappedGenericStringType, то паттерн разваливается и вся вышеописанная магия исчезает:
type MappedGenericStringType1<T, Keys extends keyof T = keyof T> = {
  [K in Keys]: any;
};

// или так
type MappedGenericStringType2<T> = keyof T extends infer Keys extends keyof T ? {
  [K in Keys]: any;
} : never;
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы