xaviergonz / mobx-keystone

A MobX powered state management solution based on data trees with first class support for Typescript, support for snapshots, patches and much more
https://mobx-keystone.js.org
MIT License
549 stars 25 forks source link

mapObject incorrect type #192

Closed SimonChaumet closed 3 years ago

SimonChaumet commented 3 years ago

When using Typescript (4.0.3) the map properties types are incorrect.

@model("TwoU/StoreCatalog")
export class StoreCatalog extends Model({
    themes: prop_mapObject(() => new Map<string, Theme>()),
    contexts: prop_mapObject(() => new Map<string, Context>()),
    scenarios: prop_mapObject(() => new Map<string, Scenario>()),
}) {
}
@withStore
@observer
class Home extends React.Component<InjectedProps> {
    render(): ReactNode {
        const {navigation, store} = this.props;
        const themes = store.catalog.themes;
        console.log("mt", themes.values()); // Typescript says that values exists but in runtime the value doesn't exist and themes is just an object
        /* console.log(getSnapshot(themes[2].contexts[0]));*/

        return <div />;
    }
}

But I can't add the getters and setters because the type is incorrect. And I can't create a getter with the same name as my property or typescript sends me a TS2611 error. What should I do ? Cast the values ?

SimonChaumet commented 3 years ago

I kind of solved the problem : my creation of my store wasn't correct, I should have used the fromSnapshot. But it seems that I can't use fromSnapshot because I'm using a rest API that don't follows your snapshot structure : we can't override the modelId (I'm using ids prefixed by the model name like themeId) and references isn't compatible with normalizr (getSnapshot gives a list of objects for references and not list of ids).

Am I missing something ? If not then maybe this library is not for me because I can't use references and fromSnapshot easily which for me are the main goals of this library.

alex-shamshurin commented 3 years ago

So this is not an issue anymore ?

SimonChaumet commented 3 years ago

If you consider that not using the lib anymore makes this not an issue then yes

alex-shamshurin commented 3 years ago

Yes, I have returned to MST after 2 days and gave up for a now. First, docs are not clear enough, even simple model ( Items maps with inner Item ) discouraged me and takes time to implement. I found out that I need to use constructor args to initialize the model, so then why default params are there ? So decided to come back later.

xaviergonz commented 3 years ago

If the data coming from a REST API doesn't include a $modelId / $modelType property you have some ways to work over it:

  1. Use functional models for that part of the data, which don't require these properties to be present (https://mobx-keystone.js.org/functionalModels)
  2. Use frozen data (assuming you don't need to do any mutations over the returned data) (https://mobx-keystone.js.org/frozen)
  3. Inject $modelId / $modelType over each of the snapshot objects / subObjects as needed (only recommended if your data structure is relatively simple)
  4. Use new Model({...}) over each of the snapshot objects / subObjects as needed (only recommended if your data structure is relatively simple)
xaviergonz commented 3 years ago

By the way, a change from MST is that even when all props have a default value you still need to provide an empty object in the constructor. At first this was (in part) to make typescript typings easier, but could be revised.

e.g.

@model("x")
class M extends Model({
  a: prop(1),
  b: prop(2)
}) {}

const m = new M({}) // empty object, indicating it will use all the default values
// m is { a: 1, b: 2 }
alex-shamshurin commented 3 years ago

I think this library will become extremely popular if someone add many examples there. Todo and list of todos are not enough. It might be users with child-parent or e-shop models with a cart....

sisp commented 3 years ago

I find it reasonably well documented, especially when you kind of know how it works. But writing good documentation is a lot of work. Just picking up a previous comment of yours: Why not learn how this library works with a "child-parent" or "e-shop models with a cart" toy example that exceeds the simplicity of a "todo list" and write it up as documentation? I think what @xaviergonz has created is terrific and IMHO way better than MST with all its flaws. But open source projects built by individuals in their free time (I assume) need community support.

xaviergonz commented 3 years ago

Closing due to inactivity