打字稿多个相同类型的泛型

Sch*_*Lex 5 generics typescript

我有很多列表需要转换为地图,所以我决定创建一个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>());
};
Run Code Online (Sandbox Code Playgroud)

该函数接受一个列表和一个返回列表元素字符串的函数。结果是一个 Map ,返回的字符串keyAccesFnas 是函数所使用的列表元素的键。

现在我不仅要提取列出的对象的 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>());
};
Run Code Online (Sandbox Code Playgroud)

问题是:我想提供一个默认的valueAccessFn,只是返回列表elemnt,所以我可以代替listToMap用listToMap2,但不能作为打字稿不接受泛型类型T1可能是泛型类型T2。这让我特别恼火,因为我没有其他地方可以通过T2.

Tit*_*mir 4

您指定的默认值有两个问题:

  1. 当您调用该函数时,Typescript 不会使用默认值进行推理,因此即使您可以设置默认值,它也不会进行推理T1=T2
  2. 由于T1T2是不同的类型,仅根据方法定义,它无法判断它将T1T2

这两个问题都可以解决,第一个问题可以通过为 指定默认值来解决T1,第二个问题可以通过使用对 any 的类型断言作为默认值来解决。

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>
Run Code Online (Sandbox Code Playgroud)