Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 297
lardratboy Avatar asked Jun 07 '26 23:06

lardratboy


1 Answers

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:

  • To use some members on a generic contraint T we need to say it must extend some interface. I created MultiGroupState for this purpose.
  • Members of the interface a numbers. So currentState , lastState and the state argument need to be numbers.
like image 121
basarat Avatar answered Jun 10 '26 20:06

basarat