Преобразование объекта на карте с помощью дженериков


Проблема

Я загружаю вещи из localStorage и это должно быть сохранено как JSON, так что он должен иметь простой Object структуру можно JSON.parse().

Однако, сом методов не приемлю <any> в качестве параметра, потому что они хотят конкретной class или interfaceно я хочу, чтобы отправить мои объект в качестве параметра, так что я должен преобразовать его в Map для того, чтобы иметь ту же структуру, но видел как он имеет тип, это сейчас принято в качестве параметра.

Моя проблема заключается в конверсии от Object для Map

Решение

public static convertObjectToMap<V>(obj: any, classOfV): Map<string, V> {
    let objectMap = new Map<string, V>();
    if (obj !== undefined && obj !== null) {
      for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
          const initObject = new classOfV(obj[key]);
          objectMap.set(key, initObject);
        }
      }
    }
    return objectMap;
  }

Я принимаю obj и class где все значения будут в одном типе.

Пример использования

//This is purely for the example
const fibonacciObject:any = {"0": 1, "1": 1, "2": 2, "3": 3, "4": 5};

const fibonacciMap:Map<string, Number> = convertObjectToMap<Number>(fibonacciObject, Number);

fibonacciMap.get("0"); //1
fibonacciMap.get("4"); //5

Вопрос

Есть ли лучший способ, чтобы сделать это преобразование, я знаю о new () => Vно поскольку мне это нужно для каждого ключа, то это не совсем оправдано.

Также, Какой тип будет class из V быть, я получаю тип ошибки, когда я пытаюсь дать ему тип



101
4
задан 3 февраля 2018 в 03:02 Источник Поделиться
Комментарии
1 ответ

Несколько моментов первый.


  1. Избежать any как чума. Вы можете почти всегда придумает лучше. Когда имеешь дело с сериализованный JSON-данные, я хотел бы иметь функцию, подобную этой, Чтобы избавиться от любого как можно скорее:

    function verify<T>(obj: any, fallback: T, isT: (obj: any) => obj is T): T {
    return isT(obj) ? obj : fallback;
    }

  2. Object.keys и Object.entries подходят для лупинга через объект, если вы собираетесь проверить hasOwnProperty. Я предпочитаю Object.entries когда это возможно, если у вас в браузере поддержку.

  3. Выбрать const или letНе смешивать их без уважительных причин. const может привести к улучшению типа умозаключений, поэтому я предпочитаю использовать его, когда это возможно.

Вот как я бы реализовать эту функцию.

function convertObjectToMap<In, Out>(
obj: { [K: string]: In } | undefined | null,
classOfIn: new (v: In) => Out
): Map<string, Out> {
const result = new Map<string, Out>();

for (const [key, val] of Object.entries(obj || {})) {
result.set(key, new classOfIn(val));
}

return result;
}

5
ответ дан 3 февраля 2018 в 08:02 Источник Поделиться