Преобразование массива строк в словарь

#typescript #typescript-typings #typescript-generics

Вопрос:

Я хотел бы иметь возможность преобразовать массив строк в словарь, где переданные строки становятся ключами объекта (и значение равно true ).:

 // obj = { foo: true, bar: true );
const obj = toObject("foo", "bar");
 

Это очень просто во время выполнения с JS, но я хочу, чтобы типы сохранялись в TS, и это удивительно сложно. Вот реализация, которая работает во время выполнения, но в конечном итоге выводит объект с типом . all Фу.

 function toObject<T extends readonly string[]>(...keys: T) {
  return keys.reduce((acc, k) => {
    acc[k] = true;
    return acc;
  }, {} as any);
}
 

При all этом мы остаемся с нулевым значением, но это все равно почти лучше, чем не указывать as any в редукторе. По крайней мере, мы можем индексировать словарь во время выполнения. Если бы мы оставили его в покое, этот тип был бы пустым объектом. Вместо этого мне нужен какой-то способ преобразования массива строк в объединение строк. Как только я это сделаю, я могу просто ввести начальное состояние редуктора в:

 {} as Record<UnionOfStrings, true>;
 

Тем не менее, я не могу понять, как сделать это преобразование.

Кто-нибудь знает, как это сделать?

Комментарии:

1. const arr = ["foo", "bar"] as const; type Union = typeof arr[number];

Ответ №1:

Вам действительно не нужно использовать .reduce для этого, так как на самом деле это не намного проще, чем просто использовать обычный старый for цикл. Вот реализация, которую я написал с использованием for цикла, но, вероятно, ее .reduce также можно написать с помощью, если вы хотите.

 function toObject<T extends readonly string[]>(...keys: T): Record<T[number], true> {
    const obj: Record<string, true> = {};

    for (const key of keys) {
        obj[key] = true;
    }

    return obj;
}
 

Обратите внимание на тип возврата: Record<T[number], true> . Я думаю, это то, что вы искали.

Комментарии:

1. аааа; рад пойти с любой петлевой структурой, но это Record<T[number], true> драгоценный камень.