How do you correctly convert Immutable Map to strictly typed using Typescript

Viewed 772

How can I convert the following from js to Typescript:

Immutable.Map({
   item1: null,
   item2: "hello",
   item3: Immutable.Map({
     item4: 2,
     item5: true
   })
});
2 Answers

I'm not familiar with the immutable.js framework, but I would suggest using a standard JavaScript map. Typescript has the type ReadonlyMap which basically removes all the setters from the map object. The object itself will not really be imputable (aka. no runtime error), but the typescript compiler will complain if you try to add/remove/update values.

const myMap: ReadonlyMap<string, string> = new Map([
    ['item1', 'foo'],
    ['item2', 'bar']
]);

console.log(myMap.get('item1')); // will log foo

myMap.set('item1', 'foobar'); // Property set does not exist on type readonly map

A bit off topic but I would suggest re-rethinking your map structure. Sure string | null is fine. But string | null | ReadonlyMap<string, number | boolean> does sound like a wird map (to me).

Also, here is the map documentation if you care to have a read.

You could do something like:

type Immutable<T> = {
  readonly [K in keyof T]: Immutable<T[K]>;
};

// Then you could write your interface 
interface Person {
  name: string;
  lastName: string;
  address: {
    street: string;
    zipCode: number;
  }
}

const person: Immutable<Person> = {
  name: 'joe',
  lastName: 'smith',
  address: {
    street: 'smith street',
    zipCode: 55555
  }
}

// Then when you try to mutate, typescript should throw an error that it is a readonly property
person.name = 'alice';
person.address.street = 'ano'

Credit goes to the author of this article linked here: https://www.sitepoint.com/compile-time-immutability-in-typescript/

Related