如何在TypeScript中使一个泛型类型紧密依赖于另一种类型? [英] How to make one generic type closely dependent on another in TypeScript?

查看:74
本文介绍了如何在TypeScript中使一个泛型类型紧密依赖于另一种类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm looking for a way to make my code more type-safe and would like to define a close relationship between some of my types when passing them to generic functions.

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

For example, for the given set of types:

interface FooParam {}
interface FooReturn {}

interface BarParam {}
interface BarReturn {}

和以下功能:

function action<T, R>(foo: T): R

我想将 FooParam FooReturn 紧密绑定,将 BarParam BarReturn 紧密绑定,因此编译器仅当一对关联类型分别作为 T R 传递时允许调用,否则返回错误.

I'd like to closely bind FooParam with FooReturn, and BarParam with BarReturn, so the compiler allows the call only if a pair of associated types is passed as T and R and returns an error otherwise.

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

我实际上已经通过定义两个基本接口来实现上述目的,这些基本接口以后将用作对通用类型的约束:

I've actually managed to achieve the above by defining two base interfaces, which will be later used as constraints on the generic types:

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 ?: T的key 字段,该字段仅存在,因此 T 实际上很重要并且已被检查,不容忽视.另一个缺点是,每种类型都必须扩展我的自定义接口之一,有时这是不可能的.

However this seems more like a workaround than a clean solution, especially given the _typeGuard?: keyof T field, which exists only so T actually matters and is checked, not ignored. Another downside is that every type must extend one of my custom interfaces, which sometimes is just not possible.

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

Is there a better and more universal way to get the described functionality?

推荐答案

您可以使用通用类型和推断.如果您的要求允许这样做,那么比从基本接口扩展每种类型都容易.此解决方案将所有链接放在一个位置,因此有其自身的缺点,但是如果您不能更改原始类型,对我来说似乎可以:

You can use a generic type and inference. If your requirements allow this, it could be easier than extending each type from base interface. This solution puts all your links in one place, so it has its own drawbacks, but it seems ok to me if you can't change original types:

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

可以看到它的行动 查看全文

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆