我有很多列表需要转换为地图,所以我决定创建一个
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
作为使用该函数的列表元素的键。
现在我不仅需要提取列出的对象的 Maps 键,还需要提取值本身。我决定通过将另一个函数传递到 listToMap 函数来解决这个问题,该函数可能会返回一个新类型。该功能类似于此 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
的东西。
您指定的默认值有两个问题:
当你调用该函数时,Typescript 不会使用默认值进行推理,因此即使你可以设置默认值,它也不会进行推理
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>