Comments 25
Не проще ли было сделать?
type MyType ="first" | "second" | ...
Не проще по двум причинам:
1) В таком случае у вас уже есть обычный массив с данными и его можно использовать, как массив во вс\м коде.
2) Мы просто выводим тип из этого массива и этот тип всегда будет синхронизирован с реальными данными в массиве.
По факту эдакая замена enum
, но с расширенными структурами данных.
Приходится повторяться потом:
const arr: MyType[] = ["first", "second", ...];
А почему не использовать enum для этих целей?
Можно и enum, но я конкретно рассматривал решение с наименьшим количеством кода.
Ну и если массив в будущем будет дополняться, нам придется в enum еще лезть и дополнять все вручную.
Так же как и в вашем случае, тоже придется дополнить варианты возможных значений))
Я это делаю один раз на месте в массиве
С enum вот так например:
enum NumberNamesEnum {
First = "first",
Second = "second",
Third = "third",
Fourth = "fourth",
Fifth = "fifth",
}
const numberNames: NumberNamesEnum[] = [
NumberNamesEnum.First,
NumberNamesEnum.Second,
NumberNamesEnum.Third,
NumberNamesEnum.Fourth,
NumberNamesEnum.Fifth,
];
И это все надо держать в актуальном состоянии, и потом чтоб использовать - импортировать везде.
Но с другой стороны такое выглядит лучше задокументированным и в сравнении с моим решением не нужно голые строки везде использовать.
Конкретно в этом случае можно сделать:
const numberNames: NumberNamesEnum[] = Object.values(NumberNamesEnum);
но если сделать "const enum", то так уже не получится.
Пожалуйста, не надо использовать енумки в качестве объектов. Они не предназначены для этого.
Вы здесь пользуетесь тем, что этот конкретный энум содержит только строковые значения. Если бы среди значений были числовые, то Object.values
перечислил бы значения как прямого отображения, так и обратного, а тайпскрипт бы ругнулся, что тип переменной numberNames
не принимает строки, которые результат функции Object.values
будет содержать. Подход же, предложенный автором статьи, годится как для строковых (или смешанных) энумов, так и для числовых.
Как минимум один плюс: для передачи литерала в качестве параметра вам не нужно дополнительно импортировать enum и искать, откуда его импортировать.
enum очень ужасен, аж один из разработчиков тайпскрипта говорил что есои бы пришлось изобретать enum сейчас то они не стали бы это делать.
Вместо enum многие (и я) пользуются объектами с последующим `keyof typeof numberNames`

А может еще добавите в статью, в какой версии TypeScript появилась возможность вот так использовать "индексатор числа [number]". Это может быть полезно для тех, кто внимательно следил за TypeScript раньше, а сейчас немного ослабил хватку :)
Спасибо. Рад в кое-то веке видеть небольшую, но информативную техническую статью на хабре.
Так же хочу показать ещё один интересный пример:
const args = [8, 5] as const;
const angle = Math.atan2(...args);
Так как к массиву применен as const
его длинна известна на стадии компиляции. Функция Math.atan2
принимает только два аргумента, и, так как компилятор знает о длине массива, позволяет использовать spread-оператор. Если убрать as const
, то компилятор не будет знать о длине массива, и не разрешит такой вызов.
Удивительно, что на две бытовых строчки кода такая объемная статься вышла. И название такое, что думал что-то необычное увидеть
Но совсем уж начинающим может пригодиться, жаль, что такую статью через Гугл не найти, слишком сложное для этого название. На вашем месте, я бы упростил
Кому интересно, какие плюсы у этого подхода:
Если смотреть фронтенд - не надо импортить везде как enum, и что ещё хуже добавлять в контекст компонента для того, чтобы он попал в рендер (привет vue2)
Удобно описать валидатор для конечной точки в цепочке компонентов (функций). В цепочке проверяем тип (и удобно указываем значения), в конце проверяем, что никто не навлевал на требуемый тип, ибо ts не гарантия :)
Я гуглил и смотрел какой перевод у понятия type inference. Везде было "Вывод типов". Решил так и использовать, хотя может можно было что-то типа "Вычисление типа по массиву строковых значений".
Статья вышла в таком объёме, в каком я сам решил для аудитории тех, кто с таким подходом не знаком, с одной стороны стараясь не поливать воду, а с другой стараясь ничего не пропустить и простым языком дать объяснение.
Вывод типов в TypeScript. Неизменяемый массив конкретных строковых значений