Reputation: 4593
I'm trying to write a d.ts
file for an API which has a collection object representing an ordered collection of key-value pairs. The keys and values are all strings. Thus, the behavior is:
thing["foo"]
returns the string value of the pair where key is "foo"thing[1]
returns the string value of the second pair in the ordered collectionthing.length
returns the count of key-value pairs as a numberI tried the following, but it produced the error "An index signature parameter must be type 'string' or 'number'
:
declare class FrobCollection {
[index: string|number] : string;
}
Is there a way to model the behavior of this object correctly in TypeScript?
EDIT: I found a way to model the two indexers, but still can't get the length
property to work.
Upvotes: 3
Views: 3760
Reputation: 220974
- thing["foo"] returns the string value of the pair where key is "foo"
- thing[1] returns the string value of the second pair in the ordered collection
- thing.length returns the count of key-value pairs as a number
The problem is that the first bullet is not true for all values of "foo"
. For example, thing["0"]
is a string, but thing["length"]
is a number, and for an arbitrary string x
you can't actually predict the type of thing[x]
The accurate definition for this type is:
declare class HeaderCollection {
length: number;
[index: number]: string;
[key: string]: number|string;
}
where it's up to the caller to ensure that they actually indexed by a value that didn't match up with some reserved name like length
, or a string that was actually a number.
Upvotes: 5
Reputation: 4593
I found a way that appears to work, though I haven't been able to test it fully yet.
declare class HeaderCollection {
[index: number] : string;
[key: string] : string;
}
I thought this would complain because TypeScript normally doesn't allow overloading, but it appears that's not the case this time. However, I'm still unable to declare the length
property of type number
, so I'm not out of the woods yet.
Upvotes: 0