Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeScript - ObservableMap to Map #1204

Closed
eddiegroves opened this issue Oct 15, 2017 · 4 comments
Closed

TypeScript - ObservableMap to Map #1204

eddiegroves opened this issue Oct 15, 2017 · 4 comments

Comments

@eddiegroves
Copy link

Just wondering if using an ObservableMap as an es2015 Map is a supported thing? TypeScript is giving a few errors

IDE: VS Code Version 1.17.0 (1.17.0)
TypeScript: 2.5.3

import { ObservableMap, observable } from "mobx";

const observableMap: ObservableMap<string> = observable.map();

const map: Map<string, string> = observableMap;
/*
[ts]
Type 'ObservableMap<string>' is not assignable to type 'Map<string, string>'.
  Property '[Symbol.toStringTag]' is missing in type 'ObservableMap<string>'.
*/

const map2: Map<string, string> = new Map(observableMap)
/*
[ts]
Argument of type 'ObservableMap<string>' is not assignable to parameter of type 'Iterable<[string, string]>'.
  Property '[Symbol.iterator]' is missing in type 'ObservableMap<string>'.
*/

const map3: Map<string, string> = observableMap.toJS();
/*
[ts]
Type 'IKeyValueMap<string>' is not assignable to type 'Map<string, string>'.
  Property '[Symbol.toStringTag]' is missing in type 'IKeyValueMap<string>'.
*/

tsconfig.json includes:

{
  "compilerOptions": {
    "target": "es2015",
    "module": "es2015",
    "lib": ["dom", "es2015", "es2016"]
  }
}
@mweststrate
Copy link
Member

I think we could ass Symbol.iterator and Symbol.toStringTag support (I think the first might already be there, just not in the typings).

But not that observable.map() instanceof Map will always yield false until we use proxies. An alternative could be to introduce a utility function that converts observable maps back to normal Map's (toJS will create a plain key/value object from the top of my head).

Alternatively, I think new Map(theObservableMap) will probably do the trick as well, although the typings might be in the way

@Strate
Copy link
Contributor

Strate commented Oct 18, 2017

There was a very similar issue about Bluebird and it assignability to Promise: DefinitelyTyped/DefinitelyTyped#11027

As @mweststrate says, instanceof check will not work, so it is a definetely not a Map. Also, for example, if you add some methods to Map's prototype, and then assign ObservableMap to variable declared as Map, and then tries to use that method, you will get an runtime error.

As for now, to solve issue with bluebird and promises, I use PromiseLike<T> interfaces, both of Promise and BLuebird assignable to it. You could also deifine MapLike interface, and use it instead of Map

@marcfallows
Copy link

Why was this closed? I would expect an ObservableMap to meet the structural requirements of Map from TypeScript's perspective (I'm not concerned with instanceof yielding unexpected results, the same way I'm not concerned that Array.isArray of an observable array is false.

Is it just a matter of typings? I get the Property '[Symbol.toStringTag]' is missing in type 'ObservableMap<string>' error so it would be good if the support could be added and/or the typings added.

I would rather not have to create a new reference (something like new Map(theObservableMap) - though the typings fail for that as well).

@mweststrate
Copy link
Member

@marcfallows a PR is welcome :)

Note that in MobX 5 this problem will probably disappear as we will proxy maps instead of having our own data structure

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants