genericstypescriptcrtp

TypeScript generics passing enumerations


First post please be kind... I recently have been tinkering with TypesScript generics and I am trying to understand something about the way generics work (or didn't in my case), I have placed the broken generic and the working version of the class in the same shared playground, hopefully it survives the trip otherwise none of this will make sense.

As you can see, the difference between the broken and working version is that I simply changed references to the enumeration into references to the generic parameter. You will notice that on the TypeScript side of the playground there are three minor problems that show up where the generic parameter is used. I thought it was a constraint problem, but after a few attempts and thanks to looking at the generated Javascript I decided I needed to find a forum and ask a question to more seasoned/expert typescript programmers.

What can I do that will coax the compiler into passing the generic types into the construction function much the same way as it does for the 'super' type? Looking at the output also explained why I was having with issues trying to use (CRTP) in a different context, what am I missing here is this possible without resorting to some crude manual edits?

-- BPT


Solution

  • This is final working code

    enum eMultiGroupState { UP, DOWN, OVER, OUT, TOTAL_STATES, DEFAULT = UP, FIRST = UP }
    class SomeBase { constructor(arg) {} children:any[] = []; }
    function Something( info, context, fn ) { fn.apply( context, info ); }
    
    interface MultiGroupState{
            FIRST:number;
            TOTAL_STATES:number;
            DEFAULT: number;        
    }
    
    class Broken<T extends MultiGroupState> {
        currentState:number;
        lastState:number;    
        activeState:any;
        constructor(public states:T,arg) {       
    
            Something( true, this, function() {
                for ( var s = states.FIRST; s < states.TOTAL_STATES; s++ ) {
                    var lower = states[s].toLowerCase();
                    for ( var child = 0, count = this.children.length; child < count; ++child ) {
                        if ( -1 !== this.children[child].name.indexOf(lower) ) {
                            this.states[ s ] = this.children[child];
                            break;
                        }
                    }
                }
                this.setState(this.states.DEFAULT );
            });
        }
        setState( state:number ) {
            if ( state === this.currentState ) return;
            this.lastState = this.currentState;
            this.currentState = state;
            this.activeState = this.states[ state ];
            for ( var i in this.states ) this.states[i].visible = (this.activeState === this.states[i]);
        }
    }
    

    Points of note: