TypeScript: копировать карту при одновременном добавлении пары ключ-значение - PullRequest
0 голосов
/ 31 декабря 2018

Я хочу элегантно скопировать структуру машинописи interfaceName (которая удовлетворяет определенному интерфейсу).Этот TypeScript содержит карту attribute3 типа Map<IKey, number>, которую, возможно, следует изменить (в зависимости от условия): необходимо вставить дополнительную пару значений ключа.

IKey, опять же,интерфейс.

interface InterfaceName{
   attribute1: string
   attribute2: string
   attribute3: Map<IKey, number>

}

interface IKey{
    a1: number
    a2: number
}

}

Моя попытка была следующей: я просто использую синтаксис ... для копирования всех членов interfaceName изатем попытайтесь присвоить attribute3 измененную копию.Но почему-то это не работает: в конце один и тот же объект Map передается из функции, независимо от логического значения.

const createModifiedCopyIfWished = (interfaceName: InterfaceName, wished: Boolean) => wished ? {
        ...interfaceName,
        attribute3: interfaceName.attribute3.set({a1:1,a2:2},5)
    }
    :
    interfaceName

let a: InterfaceName = {
    attribute1: "a",
    attribute2: "b",
    attribute3: new Map<IKey, number>()
}

let b = createModifiedCopyIfWished(a, true)

// {"attribute1":"a","attribute2":"b","attribute3":{}}
console.log(JSON.stringify(b))

Каков способ этого сделать?Возможно ли это даже в рамках одного оператора?

Рабочий пример: LiveCode

1 Ответ

0 голосов
/ 31 декабря 2018

Да, это должно быть возможно с одним оператором, например

const createModifiedCopyIfWished = (
  interfaceName: InterfaceName, 
  wished: boolean
) => wished ? {
  ...interfaceName,
  attribute3: new Map(
    [...Array.from(interfaceName.attribute3), [{ a1: 1, a2: 2 }, 123]]
  )
} : interfaceName

Это предполагает, что вы пытаетесь клонировать карту, а не просто изменить существующую.


Имейте в виду , однако, IKey, вероятно, не подходит тип ключа для Map.Map использует равенство объектов на основе идентичности (тот же самый точный объект в памяти), а не какого-либо равенства "одинаковых свойств".Таким образом, следующее не будет вести себя так, как можно было бы ожидать:

const map: Map<IKey, number> = new Map();
map.set({ a1: 1, a2: 2 }, 123);
const val = map.get({ a1: 1, a2: 2});
console.log(val); // undefined !

Это потому, что ({a1: 1, a2: 2} === {a1: 1, a2: 2}) - это false.Если вы не очень осторожны, использование объектов в качестве ключей карты - хороший способ их потерять.Единственный способ, которым объекты в качестве ключей карты работают, - это хранить где-то реальные ключи объектов и использовать их позже для поиска записей на карте.И это обычно не то, что хотят люди.

Более разумное поведение, вероятно, состоит в том, чтобы просто использовать string в качестве ключа и преобразовать предполагаемый ключ в что-то вроде JSON.stringify(objectKey) перед тем, как положить его на карту или посмотреть на него.,


В любом случае, надеюсь, это поможет.Удачи.

...