I created a function that converts an Array into a Map:
function toMap<T,TKey,TElement>(items: Array<T>,
keySelector: (item: T) => TKey,
elementSelector: (item: T) => TElement
): Map<TKey,TElement> {
var map = new Map<TKey,TElement>();
for (var item of items) {
map.set(keySelector(item), elementSelector(item));
}
return map;
}
The basic idea is to iterate through the list and apply a user-defined projection function to determine a key and value for each entry in the Map.
It's worth noting that the types TKey and TElement are determined based on the output of the projection functions provided by the user.
In most cases, the value stored in the map is simply the original element itself:
var personBySocial = toMap(people, person => person.ssn, person => person);
Hence, I wanted to set the second lambda expression as the default. Here's the revised function:
function toMap<T,TKey,TElement>(items: Array<T>,
keySelector: (item: T) => TKey,
elementSelector: (item: T) => TElement = item => item
): Map<TKey,TElement> {
var map = new Map<TKey,TElement>();
for (var item of items) {
map.set(keySelector(item), elementSelector(item));
}
return map;
}
However, there seems to be a compilation error:
Type '(item: T) => T' is not assignable to type '(item: T) => TElement'.
Type 'T' is not assignable to type 'TElement'.
Interestingly, when I pass in item => item
as a separate argument, Typescript can correctly determine that TElement equals T. Yet, if it's set as a default value, it encounters issues.
Could this be a mistake on my end, or is it a limitation of Typescript? If it's the latter, does anyone know if this issue will be resolved in upcoming updates?
EDIT, following Ryan's suggestion:
function toMap<T,TKey>(items: Array<T>, keySelector: (item: T) => TKey): Map<TKey,T>;
function toMap<T,TKey, TElement>(items: Array<T>, keySelector: (item: T) => TKey, elementSelector: (item: T) => TElement): Map<TKey, TElement>;
function toMap<T,TKey, TElement>(items: Array<T>, keySelector: (item: T) => TKey, elementSelector?: (item: T) => TElement): Map<TKey, TElement> {
var map = new Map<TKey, TElement>();
if (elementSelector)
for (var item of items)
map.set(keySelector(item), elementSelector(item));
else
for (var item of items)
map.set(keySelector(item), item);
return map;
}
I'm facing the same type error, where using map.set(keySelector(item), item)
triggers the error stating that "T is not assignable to parameter of type TElement".