2

I have this Flux Store class:

'use strict';
import flux = require('app/tools/flux');
import types = require('app/tools/types');
import Actions = require('app/actions/actions');

class Store
{
    bindListeners(config : any) : void {;};
    books : Array<types.IBook>;
    selectedBookName : string;

...
}

export = flux.createStore<Store>(Store, 'Store');

That's being used in this view:

"use strict";
import React = require('react');
import Store = require('app/stores/store'); // <-- here we import the Store
import _ = require('lodash');
import BookHelper = require('app/tools/bookHelper');
import Msg = require('app/tools/messages');

interface props {}
interface state {}

class NoteContainer extends React.Component<props, state>
{
    state: typeof Store; // <-- this is Altjs<Store>, not Store :(

    render()
    {
        if (!this.state.selectedBookName)  // <-- here's an error
            return;
...

which gives this compiles error:

error TS2339: Property 'selectedBookName' does not exist on type 'AltStore<Store>'.

How do I set the state of the view to be the actual Store class, not the AltStore<Store> class? I.e. how can I get the type of the generic parameter, like this: state: typeof Store<THIS THING>

Richard
  • 14,798
  • 21
  • 70
  • 103

1 Answers1

0

The state parameter is just a type parameter for the compiler. It is not available to you at runtime, it's just there so that methods like setState can be type-checked. From your code, though, you are exporting an instance of the store rather than the Store type itself. So you want to assign that to the state property in the constructor. Also note that type of state needs to be a plain JS object - React will use Object.assign on the state object at runtime, and it will cause problems if it isn't a plain object. So like so:

import storeInstance = require('app/stores/store');

interface StateType {
    store: AltStore<Store>;
}
class NoteContainer extends React.Component<PropsType, StateType>
{
    constructor(props: PropsType) {
        super(props);
        this.state = {store: storeInstance};
    }

Also note that you don't need to specify the type of the state property, the type parameters in the Component class definition takes care of that for you.

I'm not 100% sure about exporting an instance from a module like you're doing here, I haven't been able to get that to work, but I haven't used the require-style imports. If it doesn't work, you may need to wrap it in a function that returns the instance and export the function.

alexp
  • 3,587
  • 3
  • 29
  • 35
  • I'm not sure I understand your answer completely but I don't see how this works. On line 4 you're still making your statetype AltStore, but I need access to the type inside, Store itself. – Richard Dec 26 '15 at 18:52
  • The Store type does not really exist at runtime, other than as a function called Store when this is compile to JS, so typeof Store would just return the string 'function', which is not very helpful. If you want to add something like a class property to Store, you would have to set Store.prototype.someProperty = 'something' outside the class definition, and then you could check Store.prototype.someProperty at runtime. – alexp Dec 27 '15 at 03:04