How to declare a TypeScript indexer that accepts a string | number?
I am trying to write a file d.ts
for an API that has a collection object that represents an ordered set of key-value pairs. Keys and values ββare all strings. So the behavior is:
-
thing["foo"]
returns the string value of the pair, where the key is "foo" -
thing[1]
returns the string value of the second pair in the ordered collection -
thing.length
returns the number of key-value pairs as a number
I tried the following but it produced an error "An index signature parameter must be type 'string' or 'number'
:
declare class FrobCollection {
[index: string|number] : string;
}
Is it possible to properly model the behavior of this object in TypeScript?
EDIT: I found a way to simulate two indexers, but still can't get the property length
.
source to share
- thing ["foo"] returns the string value of the pair where the key is "foo"
- thing [1] returns the string value of the second pair in the ordered collection
- thing.length returns the number of key-value pairs as a number
The problem is that the first bullet is wrong for all values "foo"
. For example, thing["0"]
is a string, but thing["length"]
is a number, and for an arbitrary string, x
you cannot predict the typething[x]
The exact definition for this type is:
declare class HeaderCollection {
length: number;
[index: number]: string;
[key: string]: number|string;
}
where is it up to the caller to make sure they are indeed indexed by a value that doesn't match some reserved name, for example length
, or a string that was actually a number.
source to share
I found a way to work, although I haven't been able to fully test it yet.
declare class HeaderCollection {
[index: number] : string;
[key: string] : string;
}
I thought this would be complaining because TypeScript doesn't usually allow overloading, but it doesn't seem to be the case this time. However, I still can't declare a length
type property number
, so I haven't gotten out of the woods yet.
source to share