I created a helper function to convert an object of numbered keys to a Map:
interface IndexedObject {
[index: number]: unknown;
};
const objectToIndexedMap = (indexedObject: IndexedObject) => new Map(
Object.entries(indexedObject).map(
([ index, field ]) => [ Number(index), field ]
)
);
I use it to convert objects I'm getting from the API to a more convenient Map, where I don't need to deal with string keys anymore. The problem is that the returned type is Map<number, any>
, while I'd like to use the type of those values in IndexedObject
.
Is it possible to get that type and make my function return this specific type for Map values?
So for example this would throw an error:
interface IndexedNumbers {
[index: number]: number;
}
const indexedNumbers: IndexedNumbers = api.numbers; // pseudocode
const map = objectToIndexedMap(indexedNumbers);
const foo = map.get(0)!.toUpperCase(); // This should throw an error
Of course I know I can hard-type it:
const map: Map<number, number> = objectToIndexedMap(indexedNumbers);
But I'd love TypeScript to do that for me. Is it possible?
CodePudding user response:
I think It can be achieved with the help of templates
.
like this:
interface IndexedObject<T> {
[index: number]: T;
};
const objectToIndexedMap = <T>(indexedObject: IndexedObject<T>) => new Map<number, T>(
Object.entries(indexedObject).map(
([ index, field ]) => [ Number(index), field ]
)
);
Usage:
interface IndexedNumbers {
[index: number]: number;
}
const indexedNumbers: IndexedNumbers = api.numbers; // pseudocode
const map = objectToIndexedMap(indexedNumbers);
const foo = map.get(0)!.toUpperCase(); // This should throw an error