2

I am using a mapped type in my source, that I am reusing throughout my project:

type StringUnion = string | string[];
type StringUnionMap = { [key: string]: StringUnion };

I have to combine two of these maps into one map that contains the entries of both:

let map1: StringUnionMap = { "key1": "value1", "key2": "value2" };
let map2: StringUnionMap = { "key3": [ "value3a", "value3b" ] };

I can of course achieve what I want in a loop like this:

let combinedMap: StringUnionMap = {};
for (let key in map1) {
    combinedMap[key] = map1[name];
}
for (let key in map2) {
    combinedMap[key] = map2[name];
}

I find this way a bit clumsy and verbose. Is there any more concise way to combine my two maps?

I have tried this, but that does not compile transpile:

let combinedMap: StringUnionMap = new StringUnionMap( [ map1, map2 ] );

The respective JavaScript solution with Object.assign does not work, because I am targeting ES5 with noImplicitAny turned on. Therefore Object.assign is not available to me.

6
  • Why are you calling these "maps"? They are objects. Also, why do you think this is TypeScript-related? TypeScript is not the language, it's just a type layer. This is just regular old JS (or ES6) question. Commented Dec 14, 2016 at 17:33
  • Possible duplicate of How can I merge properties of two JavaScript objects dynamically? Commented Dec 14, 2016 at 17:36
  • Calm down. Please consult the answers, which suggest Object.assign or its equivalent, which is a pure ES6 construct. Commented Dec 14, 2016 at 18:21
  • It's not how "I want to call it". It's how everybody calls it, because that is the correct way to call it. There is an even better reason for not calling what you have a "map", because "map" has an extremely specific meaning in the JS world (yes, it is JS), which is a value of type Map. Anyway, your "construct" does exist in JS. All you have done is applied TS typing to a JS object, which doesn't change the fact that it is a JS object. I suggest you go back and carefully study the role of TS in the language ecosystem. Commented Dec 14, 2016 at 18:25
  • From a previous version of this question: Does typescript provide me with a more concise way to combine my two maps? TypeScript provides no new language features or new functionality. It's ES6, plus selected ES7+ features that are sufficiently advanced in the TC39 process, with typing. It adds new syntax, but that new syntax is strictly limited to specifying and handling typing information. It knows how to transpile to ES3/ES5/ES6, but in that regard is identical to Babel--yet no one would say the Babel is a language. It takes one form of JS and transpiles it into a different form. Commented Dec 14, 2016 at 19:04

2 Answers 2

6

Typescript 2.1 allows you to merge the objects using spread syntax:

let combinedMap: StringUnionMap = {...map1, ...map2};

Generated code will use Object.assign function if avaliable or provide polyfill instead:

var __assign = (this && this.__assign) || Object.assign || function(t) {
    for (var s, i = 1, n = arguments.length; i < n; i++) {
        s = arguments[i];
        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
            t[p] = s[p];
    }
    return t;
};
var map1 = { "key1": "value1", "key2": "value2" };
var map2 = { "key3": ["value3a", "value3b"] };
var combinedMap = __assign({}, map1, map2);
Sign up to request clarification or add additional context in comments.

Comments

0

Typescript doesn't give you functionality like that, but javascript has the Object.assign function which does pretty much what you're looking for:

type StringUnion = string | string[];
type StringUnionMap = { [key: string]: StringUnion };

let map1: StringUnionMap = { "key1": "value1", "key2": "value2" };
let map2: StringUnionMap = { "key3": ["value3a", "value3b"] };

let combinedMap: StringUnionMap = Object.assign({}, map1, map2);
console.log(combinedMap); // Object {key1: "value1", key2: "value2", key3: Array[2]}

(code in playground)

3 Comments

Why "pretty much"? Isn't it "exactly"?
I have tried this option and it doesn't work. The reason is that I am targeting ES5.
Object.assign does not verify types integrity. See code in playground

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.