TS Array tips

У нас возникла проблема на уровне типов - забрать у массива все его ключи. Если для объекта у нас keyof то и для массива это тождество должно быть верным? Да, подумал я и попробовал сделать следующее const arr = [1,2,3] as const

type Arr = typeof arr type Keys = keyof Arr

По итогу в типе Keys у нас хранятся не только ключи, но и методы объекта. Такие как at, slice, push, и др.

Далее я попробовал забрать ключи через Extract по числам, логично же Проблема в том, что keyof возвращает для массива возвращает строки, т.е. в примере будет тип KeysActual type KeysExpected = 0 | 1 | 2 | "at" | ... type KeysActual = "0" | "1" | "2" | "at" | ...

Поэтому далее я решил забрать числовой строковый тип. Получилось вот так type Arr = [1,2,3] type AllKeys = keyof Arr type KeysAsString= Extract type Res = KeysAsString // "0" | "1" | "2"

Это позволило взять все числовые типы, которые объявлены в виде строки. А если нам надо тотже тип, но не в виде строки, то придется воспользоваться infer type Arr = [1,2,3] type AllKeys = keyof Arr type KeysAsString= Extract type KeysAsNumber= KeysAsStringextends ${infer Num extends number} ? Num : never

type Res = KeysAsNumber // 0 | 1 | 2 ....

А если нам надо преобразовать массив в объект, то достаточно написать следующий подтип type ArrayToRecord = {

};

type Arr = [1,"qwe"] type Res = ArrayToRecord // {0: 1, 1:"qwe"}

Вот такой вот коварный keyof, сначала ты знаешь как он работает для объекта, а для массива он дает другой результат

#tip_of_the_day #ts @haradkou_sdet