37

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.

2 Answers 2

58

Use an index signature:

declare var Game: {
    creeps: {[key:string]: Creep}
};
Sign up to request clarification or add additional context in comments.

4 Comments

Perfect, thank you! Didn't know what to search for. Will accept in ~5min
This still errors in VSCode. Is that a bug in VS Code or is there another way to say "any property is OK"?
You need to access it as a dictionary i.e. creeps['key'] instead of creeps.key. If you know the key name then you should add it as a standard prop instead of using an index signagure
Aha! I didn't expect those behave differently. Thanks again :-)
13

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.

1 Comment

There's a new flag in TS 4.1 that will treat all index signatures as optional if you want to get a warning for that. --noUncheckedIndexedAccess

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.