Возможно ли в TypeScript объявить тип свойств в объекте, если они добавляются динамически?

#typescript

#typescript

Вопрос:

У меня есть такой метод.

 private getStuff(data: string[]) : CertainType[] { ... }
  

Я решил, что имеет больше смысла иметь выходные данные в виде словаря (C #’ish), чем массива. Насколько мне подсказывает мой google-foo, я должен использовать объект и вставлять в него данные с идентификатором в качестве имен полей. Поэтому вместо:

 const things: Thing[]; ...
things = [];
output.push(thingy);
console.log(things[3]);
  

Я делаю это:

 const stuff: any; ...
stuff = { };
stuff[3] = stuffy;
console.log(things[3]);
  

Итак, подпись метода изменилась на это.

 private getStuff(data: string[]) : any { ... }
  

Все это работает просто великолепно, но. Мне нравятся полужесткие типизированные переменные в TypeScript, и исходя из C #, я твердо верю в то, что можно избежать многих проблем, будучи (по-видимому) придирчивым заранее (не попадая в диапазон PO. конечно).

Поскольку количество свойств заранее неизвестно, равно как и их идентификаторы, мне интересно, является ли any ближайшим параметром типа или есть что-то, соответствующее синтаксису C # как:

 Dictionary<string, Thing> dicky;
  

Ответ №1:

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

Это может быть записано как

 const stuff: Record<string, Thingy> = {};
  

Или, более подробно, но эквивалентно:

 const stuff: { [index: string]: Thingy } = {};
  

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

1. Как говорится в Amazing Grace: » О, я был слеп, но теперь я C # «… Идеально! Я собираюсь сразу же переработать некоторый код.

2. @KonradViltersten рад слышать, не забудьте проголосовать и отметить как ответивший 🙂

3. Тогда не спешите с ответом. Я нажимал «принять», но мне сказали подождать 59 секунд. Вы просто слишком полезны. 🙂

4. Верно, поскольку мы ждем принятия временного блока — в первом примере вы предполагаете, что у меня есть класс с именем Record , верно? Если у меня нет специализированного класса для этого, я должен использовать подробный синтаксис,. Это правильно понято?

5. @KonradViltersten нет, Record предопределено, вы можете его использовать. По сути, это одно и то же Record<string, Thingy> == { [index: string]: Thingy }