如何在 TypeScript 中键入此默认值?

How does one type this default value in TypeScript?

抱歉标题模糊,但我不知道如何简洁地表达这个问题。

基本上,我有以下代码(删除了不重要的位):

function identity<T>(value: T): T {
    return value;
}

function extent<T, K>(
    values: T[],
    map: (value: T) => K = identity // the '= identity' part gives an error
): [K, K] | undefined {
    let min;
    let max;

    // ... stuff ...

    return min === undefined || max === undefined ? undefined : [map(min), map(max)];
}

默认 = identity 值会导致编译器错误。

我可以从 extent 的签名中删除 map 参数的默认值,并始终自己提供一个:

extent([5, 1, 3, 4, 8], x => x)

这会工作得很好,但我宁愿不提供第二个参数,除非我实际上是将值从一种类型映射到另一种类型。

如何键入 indentity 函数,以便它被接受为 extentmap 参数的默认值?我暂时坚持使用 TypeScript 3.6,如果这很重要的话。

这是因为类型错误。

map 参数中,您声明此函数将 return K 的类型,但在 identity 函数中,您希望 return T 的类型,因此您不能将其指定为默认值。

你可以这样修正:map: (value: K) => K = identity

T => K 映射类型与身份函数中的 K => K 类型存在冲突。降低 identity 对类型的严格程度有助于:

function identity<T>(value: T): any {
    return value;
}

甚至

const identity = (x: any) => x;

可能对外界保持类型安全的最佳处理方式是通过重载:

function extent<T>(values: T[]): [T, T] | undefined
function extent<T, K>(values: T[], map: (value: T) => K): [K, K] | undefined
function extent<T, K>(
  values: T[],
  map?: (value: T) => K 
): [K, K] | [T, T] | undefined {
  const actualMap = map ?? identity;
  let min;
  let max;

  // ... stuff ...

  return min === undefined || 
         max === undefined ? 
             undefined : 
             [actualMap(min), actualMap(max)];
}