Indexers in newest compiler version (0.9.5)

Topics: General
Dec 12, 2013 at 11:04 AM
Edited Dec 12, 2013 at 3:25 PM
Hello everyone.

After updating to 0.9.5 I've found some errors in the defenition for js-library.
Let me explain the situation through the code.
It is my JavaScript code:
var Sample = lib.ClassImpl({
    ctor: function(array) {
        var me = this;

        this._items = array;
        this._items.forEach(function(name) {
            me[name] = new ItemWrapper(name); //Implemetation of ItemWrapper is unnecessary
        });
    },

    doSomething: function() {
        //some logic, no return
    },

    returnSomething: function() {
        return this._items.length;
    }
});
And this is the usage:
var sample = new Sample(["First", "Second", "Third"]);
sample.doSomething();
console.log(sample.returnSomething());
console.log(sample.First.method());
console.log(sample.Third.method());
In typescript defenitions which I've wrote for previous version of TypeScript compiler (0.9.1.1) I was able to do:
export interface ISampleBase {
    doSomething(): void;
    returnSomething(): number;
}
export interface ISample extends ISampleBase {
    [name: string]: ItemWrapper; //here is the error
}
export class Sample implemets ISampleBase {
    constructor(array: string[]);
    doSomething(): void;
    returnSomething(): number;  
}
And then use it in my ts-file (intellisense work like a charm):
var sample: ISample = new Sample(["First", "Second", "Third"]);
sample.doSomething(); 
sample["Third"].method();
But after update to version 0.9.5 I've got an error, that all named properties must by subtypes of string indexer type ItemWrapper on line above that marked by comment.
Is there any variants for me to resolve the issue?

upd: Link to example.
Coordinator
Dec 12, 2013 at 4:17 PM
With 0.9.5, we've been tightening the type checker to enforce the language spec rules more closely. One area that's gotten some attention is the indexer. Looking at what the merged form of ISample looks like:
export interface ISample {
    doSomething(): void;
    returnSomething(): number;
    [name: string]: ItemWrapper; //here is the error
}
The indexer here states that for any property access with the indexer, an ItemWrapper is returned. Any time this isn't the case, the compiler will warn you. While you might read this as "indexing with any value other than one of the property names", it turns out this can't be checked.
var s;
if (somerandomnumber()) {
  s = "returnSomething";
}
else {
  s = "somethingElse";
}
var is: ISample;
var y = is[s];
The indexer then covers everything in this case, so that's why we do the subtype check to make sure all the properties match what the indexer says. It's tempting to wonder why we can't treat explicit property accesses and indexed accesses differently, which would allow this to continue working. Unfortunately, treating them as separate makes a distinction that JavaScript doesn't make - namely that both accessing via a '.' or through an indexer should be equivalent.

This makes it difficult to model the "everything else" use for the indexer, like your example.