mpen
mpen

Reputation: 282805

How to declare a typed object with arbitrary keys?

In a .d.ts file, how do I define an object as having string keys and T values?

e.g.

declare var Game: {
    creeps: Object<string, Creep>; // not sure what syntax to use here
};

declare class Creep {
   // definition...
}

Game.creeps is an object, but I don't know what properties/keys it will have (they're defined at run time -- I'm using it like a dictionary), however, I do know that all its values will be Creeps.

My IDE says "Object is not generic" so I guess that syntax isn't quite right.

Upvotes: 37

Views: 20187

Answers (2)

ocket8888
ocket8888

Reputation: 1140

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.

Upvotes: 13

basarat
basarat

Reputation: 276181

Use an index signature:

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

Upvotes: 58

Related Questions