24

I would like to create a Map interface in TypeScript but I cannot seem to figure out how to constrain the property accessor to please the compiler

Desired Interface

export interface IMap<I extends string | number, T> {
  [property: I]: T;
}

Error:

An index signature type must be 'string' or 'number'

2
  • you're trying to create a generic. Commented Jan 8, 2016 at 21:18
  • 1
    indeed you can only do this with string or number as of today Commented Jan 8, 2016 at 21:19

1 Answer 1

36

You are allowed to define both a string and numeric index signature.

From the spec:

An object type can contain at most one string index signature and one numeric index signature.

So you can do this:

interface IMap<T> {
    [index: string]: T;
    [index: number]: T;
} 

Is that what you were after?

Also, when you define only a string index signature:

Specifically, in a type with a string index signature of type T, all properties and numeric index signatures must have types that are assignable to T.

And so:

class Foo {
    [index: string]: number;
}

let f = new Foo();

f[1] = 1; //OK

f[6] = "hi"; //ERROR: Type 'string' is not assignable to type 'number'
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, however I was looking to be able to use the interface as IMap<number, string> or IMap<string, string> defining the index type per usage. It appears this is not possible.
Ah, OK. Yeah, you are right. You could create two separate interfaces, but that sort of defeats the purpose.
Yeah, there's only two types it could be. If TypeScript allowed indexing via Enums there'd be more need for a generic.

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.