我写了一个函数来投影阵列成地图:打字稿类型推断失败?
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;
}
基本上,遍历列表并调用用户提供的投影功能,提取地图键和值。
注意,类型TKEY的和TElement从的投影函数的返回值infered在传递
大多数的时候,值在地图仅仅是原始的元素:
var personBySocial = toMap(people, person => person.ssn, person => person);
所以我想让第二个lambda默认。很容易的:
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;
}
然而,这将产生一个编译错误:
Type '(item: T) => T' is not assignable to type '(item: T) => TElement'.
Type 'T' is not assignable to type 'TElement'.
出于某种原因,如果我在分别通过item => item
,打字稿可以推断,TElement == T,但如果我将它传递在默认情况下,它不能。
我在这里做错了什么,或者这是目前的Typescript限制?如果是后者,是否有人知道这是未来将要解决的已知问题?
编辑,响应莱恩的评论:
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;
}
我运行到同一类型的错误,其中的else子句中的map.set(map.set(keySelector(item), item)
)被触发的错误第二个item
表示“T不能分配给TElement类型的参数”。
该申诉是非常合情合理的。当我尝试实现第一个示例(两个签名)时,我遇到了相同类型的错误。我在我的帖子中包含了我的代码。 – Mud