typescript - 如何在 TypeScript 中使一种泛型类型紧密依赖于另一种泛型类型?

标签 typescript generics

我正在寻找一种方法来使我的代码更安全,并希望在将某些类型传递给泛型函数时定义它们之间的密切关系。

例如,对于给定的一组类型:

interface FooParam {}
interface FooReturn {}

interface BarParam {}
interface BarReturn {}

和以下功能:
function action<T, R>(foo: T): R

我要紧密绑定(bind)FooParamFooReturn , 和 BarParamBarReturn ,因此编译器仅在一对关联类型作为 T 传递时才允许调用和 R否则返回错误。
action<FooParam, FooReturn>(...) // bound types, OK
action<BarParam, BarReturn>(...) // bound types, OK

action<FooParam, BarReturn>(...) // types are not bound, ERROR
action<FooParam, string>(...) // types are not bound, ERROR

实际上,我已经通过定义两个基本接口(interface)来实现上述目标,这些基本接口(interface)稍后将用作泛型类型的约束:
interface Param {}
interface Return<T extends Param>{
    _typeGuard?: keyof T
}

interface FooParam extends Param {}
interface FooReturn extends Return<FooParam> {}

interface BarParam extends Param {}
interface BarReturn extends Return<BarParam> {}

function action<T extends Param, R extends Return<T>>(foo: T): R

然而,这似乎更像是一种解决方法,而不是一个干净的解决方案,尤其是考虑到 _typeGuard?: keyof T字段,仅存在于 T实际上很重要并且被检查,而不是被忽略。另一个缺点是每种类型都必须扩展我的一个自定义接口(interface),这有时是不可能的。

是否有更好、更通用的方法来获得所描述的功能?

最佳答案

您可以使用泛型类型和推理。如果您的要求允许这样做,它可能比从基本接口(interface)扩展每种类型更容易。此解决方案将您的所有链接放在一个地方,因此它有其自身的缺点,但如果您不能更改原始类型,我似乎可以:

type Return<T> =
  T extends BarParam ? BarReturn :
  T extends FooParam ? FooReturn :
  never;

你可以看到它在行动Playground

关于typescript - 如何在 TypeScript 中使一种泛型类型紧密依赖于另一种泛型类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61639400/

相关文章:

Angular 2 : Binding dropdowns values with 'n' numbers

javascript - Angular - 在调整大小时更改 html 元素

javascript - 在 Canvas 上裁剪视频

scala - Scala 中的子类型和类型参数

java - 泛型和数组

java - 使用泛型的 Collector.toMap

c# - 如何在方法中返回动态返回类型? C#

javascript - 如何从组件更改服务变量的值?

javascript - Angular 2 如何在按钮返回时模糊输入?

generics - Scala 类无法覆盖扩展 java.util.comparator 的 Java 接口(interface)中的比较方法