10

I'm trying to covert the following array to a Map:

const arr = [
  { key: 'user1', value: { num: 0, letter: 'a' } },
  { key: 'user2', value: { num: 0, letter: 'b' } },
  { key: 'user3', value: { num: 0, letter: 'c' } },
];

What I have so far:

const arr = [
  { key: 'user1', value: { num: 0, letter: 'a' } },
  { key: 'user2', value: { num: 0, letter: 'b' } },
  { key: 'user3', value: { num: 0, letter: 'c' } },
];
const b = arr.map(obj => [obj.key, obj.value]);
const map = new Map<string, { num: number; letter: string }>(b);

console.log(map.get('user1'));

Do you know if this is something achievable?

PS: You can find Typescript playground here and the error that I'm getting

2
  • If you do it all in one line TypeScript infers the correct type playground const map = new Map(arr.map(obj => [obj.key, obj.value])); Commented Jan 30, 2023 at 22:08
  • 1
    const map = new Map(arr.map(obj => [obj.key, obj.value])); Commented Jan 30, 2023 at 22:09

1 Answer 1

22

obj.key is a string, and obj.value is a {num: number, letter: string}, so if you make an array of them ([obj.key, obj.value]), then you get an Array<string | {num: number, letter: string}>.

You need to tell TypeScript that you're creating a specific tuple, as expected by the Map constructor, not a generic array. There are a few ways of doing this:

// The simplest: Tell TypeScript "I mean exactly what I said."
// (This makes it readonly, which isn't always desirable.)
const b = arr.map(obj => [obj.key, obj.value] as const);

// Or be explicit in a return type. You can do this at a few levels.
const b = arr.map<[string, { num: number, letter: string}]>(obj => [obj.key, obj.value]);
const b = arr.map((obj): [string, { num: number, letter: string}] => [obj.key, obj.value]);

// Or, as explained in the comments, do it in one line, and TypeScript
// can infer tuple vs. array itself.
const map = new Map(arr.map(obj => [obj.key, obj.value]));
Sign up to request clarification or add additional context in comments.

Comments

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.