Безопасный от типа способ получить строковый литерал массива <const>со строками - PullRequest
0 голосов
/ 14 мая 2019

С появлением TypeScript 3.4 у нас теперь есть const contextx . Это может быть очень полезно, если вы хотите указать список допустимых констант для параметра (-ов) функции или аналогичного, не называя каждого из них:

export const validValues = [
    'Audi',
    'BMW',
] as const;

Я хочу использовать этот синтаксис для замены обычного способа определения строковых литералов «фиктивными именами»:

export const AUDI = 'Audi';
export const BMW = 'BMW';

Используя код Visual Studio, я застрял в том, как я могу получить доступ к этим литералам из validValues, используя строковые индексы вместо числовых индексов.

При написании validValues[... код Visual Studio будет правильно предлагать validValues[0] или validValues[1], поскольку тип validValues представляет собой двухэлементный массив (или кортеж). Это, однако, не так читаемо, как запись `validValues ​​[" Audi "].

Вот ссылка на изображение кода Visual Studio, автоматически предлагающее доступные значения ! (Недостаточно репутации для публикации изображения.)

К сожалению, здесь нет кода VS, предлагающего его, поскольку он семантически неверен (массив проиндексирован) и, таким образом, вернет undefined.

Это просто несбыточная мечта или правильный синтаксис для нее?

1 Ответ

0 голосов
/ 20 мая 2019

Это похоже на случай использования, когда enum может быть достаточным, но ключи и значения перечисления обычно не совпадают, если вы не установите их вручную таким образом.

Если выЕсли вам нужен объект, в котором каждое свойство в ключе K имеет значение K, то вам нужно создать его самостоятельно, так как в JavaScript / TypeScript такой встроенной структуры данных не существует.

К счастью, вы можете создать функцию для создания подобного вам объекта:

function validValueMaker<T extends string>(...args: T[]) {
    const ret = {} as { [K in T]: K };
    args.forEach(v => ret[v] = v);
    return ret;
}

И использовать его так:

const validValues = validValueMaker("Audi", "BMW");

// IntelliSense prompts these:
validValues.Audi;
validValues.BMW;

Соответствует ли это вашим потребностям?Надеюсь это поможет;удачи!

...