How to declare a typed object with arbitrary keys?

Use an index signature:

declare var Game: {
    creeps: {[key:string]: Creep}
};

basrat's answer still works fine but, in Typescript 2.1 or higher, there is a typing that looks more similar to what you originally thought might work:

declare var Game: {
    creeps: Record<string, Creep>
};

There's no real difference, though I'd add that Typescript assumes that for any K value a Record<K, V> can produce a corresponding V value. For example:

type Creep = {
    id: number;
}

function printIt(c: Creep) {
    console.log(c.id);
}

let game: Record<string, Creep> = {"test": {id: 0}};
printIt(thing["quest"]);

will compile - even with strictNullChecks - although it will definitely result in a run-time error. So you need to check index access yourself, and/or use the --noUncheckedIndexedAccess flag as @mpen suggested.

Tags:

Typescript