我有很多需要传递给地图的列表所以我决定创建一个listToMap
函数:
export function listToMap<T>(
list: T[],
keyAccesFn: (listElement: T) => string): Map<string, T> {
const reducer = (accumulator: Map<string, T>, currentValue: T) => accumulator.set(keyAccesFn(currentValue), currentValue);
return list.reduce(reducer, new Map<string, T>());
};
该函数接受一个列表和一个返回列表元素字符串的函数。结果是一个Map,返回的字符串keyAccesFn
作为该函数使用的侦听器的键。
现在我发现我不仅需要提取列出的对象的地图键,而且还要提取值本身。我决定通过将另一个函数传递给listToMap函数来解决这个问题,该函数可能返回一个新的Type。该函数看起来像这个atm:
export function listToMap2<T1, T2>(
list: T1[],
keyAccesFn: (element: T1) => string,
valueAccesFn: (element: T1) => T2 = (element: T1) => element): Map<string, T2> {
const reducer = (accumulator: Map<string, T2>, currentValue: T1) => accumulator.set(keyAccesFn(currentValue), valueAccesFn(currentValue));
return list.reduce(reducer, new Map<string, T2>());
};
问题是:我想提供一个默认的valueAccessFn
,只返回列表元素,这样我可以用listToMap2
替换listToMap,但不能像打字稿一样不接受泛型类型T1
可能是泛型类型T2
。这让我特别恼火,因为我没有其他地方通过T2
的任何事情。
答案 0 :(得分:2)
您指定的默认值存在两个问题:
T1=T2
T1
和T2
是不同的类型,因此根据方法定义,它无法判断T1
是否与T2
兼容这两个问题都可以解决,第一个是通过为T1
指定默认值,第二个是通过对任何默认值使用类型断言来解决。
export function listToMap2<T1, T2 = T1>(
list: T1[],
keyAccesFn: (element: T1) => string,
valueAccesFn: ((element: T1) => T2) = ((element: T1) => element) as any): Map<string, T2> {
const reducer = (accumulator: Map<string, T2>, currentValue: T1) => accumulator.set(keyAccesFn(currentValue), valueAccesFn(currentValue));
return list.reduce(reducer, new Map<string, T2>());
};
listToMap2([''], k=> k) // Map<string, string>
listToMap2([''], k=> k, k=> k.length); //Map<string, number>