Skip to content

Instantly share code, notes, and snippets.

@thomasboyt
Created April 7, 2016 22:56
Show Gist options
  • Save thomasboyt/9118837681a33c3a2d3b5ab58db4d2e2 to your computer and use it in GitHub Desktop.
Save thomasboyt/9118837681a33c3a2d3b5ab58db4d2e2 to your computer and use it in GitHub Desktop.
/*
* Immutable JS's Record type allows you define maps that you can access with
* standard dot-notation instead of a get() method. It's mainly used for
* defining the shape of complex objects, such as the root state of a Redux
* component.
*
* Unfortunately, they basically don't work in TypeScript. Check this out:
*/
import * as I from 'immutable';
const StateRec = I.Record({
a: 1,
b: 'foo'
});
// We can define a class for this record extending I.Record.Class to specify
// the properties:
class State extends StateRec {
a: number;
b: string;
}
// state is an instance of the State class
const state = new State();
// Here, typescript will correctly tell you that state.a and state.b are a
// string and number:
console.log(state.a);
console.log(state.b);
// This is where things go awry. The methods on I.Record.Class are inherited
// from I.Map<string, any>, which means that they return instances of
// I.Map<string, any>. Below, stateP is one of these instances:
const stateP = state.set('a', 2);
// And thus this will fail to type-check:
console.log(stateP.a); // Property 'a' does not exist on type 'Map<string, any>'
// We can try to manually specify the type, but this fails too:
const statePAssigned: State = state.set('a', 2);
// Type 'Map<string, any>'' is not assignable to type 'State'
// It may be possible to fix this with the new `this` type feature in TypeScript:
// https://github.com/facebook/immutable-js/issues/800
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment