I have a function that groups an array and returns a Map:
function groupBy<ListValueType, KeyValueType extends String|Number>(
list: ListValueType[],
keyGetter: (elem: ListValueType) => KeyValueType)
: Map<KeyValueType, ListValueType[]>
{
const map = new Map<KeyValueType, ListValueType[]>();
list.forEach((item: ListValueType) => {
const key = keyGetter(item);
const collection = map.get(key);
if (!collection) {
map.set(key, [item]);
} else {
collection.push(item);
}
});
return map;
}
ok, this works fine in a standard setting:
const arr = [1,2,3,4,5,6]
const map = groupBy(arr, x => x < 4 ? 'small' : 'large')
but this does not work if the ListValueType is unknown
function someFunction(list) { // list implicitly has 'any' type
const map = groupBy(list, elem => elem.myProperty) // Error TS18046 elem is inferred as 'unknown'
}
If I removed all type information on my function, typescript would not complain about unknown type.
can I relax my typisation such that the above code is accepted.
I know that any type casts would help, but don't want to change all calls to this function:
function someFunction(list) { // list implicitly has 'any' type
const map = groupBy(<any[]>list, elem => elem.myProperty) // no type error
}
using a default type is possible `ListValueType = any` and does the job:
function groupBy<KeyValueType extends String|Number, ListValueType = any>(
list: ListValueType[],
keyGetter: (elem: ListValueType) => KeyValueType)
: Map<KeyValueType, ListValueType[]>
{
const map = new Map<KeyValueType, ListValueType[]>();
list.forEach((item: ListValueType) => {
const key = keyGetter(item);
const collection = map.get(key);
if (!collection) {
map.set(key, [item]);
} else {
collection.push(item);
}
});
return map;
}