TypeScript 保留泛型函数返回类型中的传递参数类型,

pbwdgjma  于 4个月前  发布在  TypeScript
关注(0)|答案(2)|浏览(41)

搜索词

generic, propagate, multiple, preserve, argument, parameter, pass-through

建议

当一个泛型函数用参数约束表达其返回类型时,调用该函数时应保留/传递原始给定的参数类型。

示例

interface HasId {
  id: string;
}

interface SpecialArray<D> {
  getSpecialItem(): D;
}

function go<T extends Array<D>, D>(x: T): SpecialArray<D> {
  return x as any;
}

const v: Array<HasId> = [{id: 'one'}];

// We expect a return type of `SpecialArray<HasId>` but instead we
// get `SpecialArray<{}>`.
const w = go(v);

(playground)

用例

我的主要用例是组合式mixin。我想能够使用类似 HasItems<SomeItem> 类型的类,并通过mixin添加行为 HasActiveItem<D> ,其中mixin识别传入的 SomeItem 并将其传播以满足后续mixin调用。
今天可以通过省略函数签名中的一个泛型并在参数和返回类型中复制这些类型来实现这一点;剩余的泛型只捕获签名中的 "Item" 部分。

检查清单

  • 这不会对现有的TypeScript/JavaScript代码造成破坏性更改
  • 这不会改变现有JavaScript代码的运行时行为
  • 这可以在不根据表达式的类型发出不同的JS的情况下实现
  • 这不是一个运行时特性(例如库功能、JavaScript输出的非ECMAScript语法等)
  • 这个特性将与 TypeScript's Design Goals 的其他部分保持一致。
cs7cruho

cs7cruho1#

Typescript不会推断未在函数参数中使用的类型参数。其他类型参数(据我所知)不是类型参数的推断站点。
要使上述代码正常工作,有几种方法:

  1. 可以使用D并删除T:
function f<T extends object>(x: T): T {
  return x;
}
  1. 可以使用T并使用条件类型提取项类型:
function f<T extends object, U extends object>(x: T): U {
  if (typeof x === 'object') {
    return x as U;
  } else {
    return x;
  }
}

虽然你的代码可以正常工作,但由于已经有实现相同功能的方法,所以不确定从一个类型参数推断另一个类型参数所需的额外复杂性是否合理。

jdgnovmf

jdgnovmf2#

@dragomirtitian 的分析是正确的。
如果没有使用案例需要新的功能,这里就没有建议。通用函数已经在许多适当的地方被推断出来,但OP中描述的函数不需要这样做。

相关问题