1

First things first, I'm using these classes:

class Student {
  name: string;
  age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

class Food {
  flavor: string;
  portions: number;
  constructor(flavor: string, portions: number) {
    this.flavor = flavor;
    this.portions = portions;
  }
}

Basically what I'm doing is that:

const food_backpack = new Map<Student, Food>()

const sam = new Student('Sam', 15);
const ariana = new Student('Ariana', 18);

const cheese = new Food('Fetta', 5);
const chocolate = new Food('Twix', 2);

food_backpack.set(sam, cheese);
food_backpack.set(ariana, chocolate);

Well that worked.

But I'm trying to use the constructor instead to initialize the map values which IS NOT WORKING for me (compile time errors). I tried this below:

const sam = new Student('Sam', 15);
const ariana = new Student('Ariana', 18);

const cheese = new Food('Fetta', 5);
const chocolate = new Food('Twix', 2);

const bi_sam = [sam, cheese];
const bi_ariana = [ariana , chocolate];

const food_backpack = new Map<Student, Food>([
  bi_sam,
  bi_ariana
]);

And this below:

const sam = new Student('Sam', 15);
const ariana = new Student('Ariana', 18);

const cheese = new Food('Fetta', 5);
const chocolate = new Food('Twix', 2);

const bi_sam = [(sam as Student) , (cheese as Food)];
const bi_ariana = [(ariana as Student) , (chocolate as Food)];

const food_backpack = new Map<Student | Food, Food | Student>([
  bi_sam,
  bi_ariana
]);

Something that uses the constructor way and THAT WORKED is:

const sam = new Student('Sam', 15);
const ariana = new Student('Ariana', 18);

const cheese = new Food('Fetta', 5);
const chocolate = new Food('Twix', 2);

const food_backpack = new Map<Student, Food>([
  [sam, cheese], 
  [ariana, chocolate]
]);

But I don't prefer it.

Thanks for your precious time and effort!

4
  • What's "NOT WORKING" mean exactly, errors etc Commented Aug 21, 2020 at 21:41
  • compile time errors Commented Aug 21, 2020 at 21:42
  • Argument of type '(Student | Food)[][]' is not assignable to parameter of type 'ReadonlyArray<[Student | Food, Student | Food]>'. Type '(Student | Food)[]' is missing the following properties from type '[Student | Food, Student | Food]': 0, 1 Commented Aug 21, 2020 at 21:44
  • Without a context, like an argument list, to guide inference array types are inferred instead of tuple types. Commented Aug 21, 2020 at 22:34

2 Answers 2

4

TypeScript is unable to match the signature you provided and the one that is passed by the arguments. Mainly, the values are readonly in a Map.

You can create a new type like,

type StudentRecord = readonly [Student, Food];

And now your Map constructor should work as intended:


const sam = new Student('Sam', 15);
const ariana = new Student('Ariana', 18);

const cheese = new Food('Fetta', 5);
const chocolate = new Food('Twix', 2);

type StudentRecord = readonly [Student, Food];

const bi_sam: StudentRecord = [sam, cheese];
const bi_ariana: StudentRecord = [ariana , chocolate];

const food_backpack = new Map<Student, Food>([
  bi_sam,
  bi_ariana
]);
Sign up to request clarification or add additional context in comments.

5 Comments

that I like. Thankss alott!! Btw I saw those weird constructs you’re suggesting but didn’t understand there real purpose until now. I’ll test tomorrow and let you know if all goes to plan.
Sure thing, you can learn more about how generics work in the official handbook.
You can also just write const bi_sam = [same, cheese] as const;
I tried the 'StudentRecord' and the 'as const' solutions and I still get compile time errors. I'm working on repl.it/languages/typescript . Is this compiler outdated?
Yes, that appears to be running v3.3.3. readonly Tuples were added in v.3.4. I'd recommend the official playground available, it has versions you can switch too.
-1

As we can see at Map mdn page it takes arguments like this:

new Map([
  [1, 'one'],
  [2, 'two'],
  [3, 'three'],
])

So it's an array of two-element array. First element is a key and second a value. So it perfectly explain why it works with:

new Map<Student, Food>([
  [sam, cheese], 
  [ariana, chocolate]
])

but now with:

new Map<Student, Food>([
  bi_sam,
  bi_ariana
])

1 Comment

I read that page and that’s what puzzles me. My bi_sam and bi_ariana are just variables representing the exact same thing. I’m starting to get a feel that I’m creating an array of array pointers instead of array of bi-value arrays. What’s your thoughts on that? And why typescript won’t work it out on its own?

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.