在打字稿中的泛型中使用泛型

时间:2021-02-25 02:40:54

标签: typescript generics

所以假设我有这样的事情:

type Id<T> = T;
const f = <B>(a: Id<B>, b: B): [Id<B>, B] => [a, b];

但我想扩展 f 以便能够使用其他依赖类型

type List<T> = T[];

我怎样才能实现类似的目标

const f = <A, B>(a: A<B>, b: B): [A<B>, B] => [a, b];
f<Id, number>(1, 2) // evaluates to [1,2]
f<List, number>([1], 2) // evaluates to [[1],2]

没有打字稿抱怨 A 不是通用的吗?还是传递给泛型的类型必须是平面类型?

1 个答案:

答案 0 :(得分:0)

不幸的是,TypeScript 不直接支持您想要 A 的那种更高种类的类型 (HKT)。并且您不能在不立即为某些 Id 指定其类型参数(如 Id<T>)的情况下引用 T。请参阅 microsoft/TypeScript#1213 以获取对更高级类型的长期开放功能请求。该问题确实列出了一些可以在 TypeScript 中模拟/模拟 HKT 的方法,但还不够好,我真的推荐它。

例如,您可以执行以下操作,通过 merging it into an interface declaration 显式注册您关心的每个更高级的类型:

type Id<T> = T;
interface HKTRegistry<T> { Id: Id<T> };

type List<T> = T[];
interface HKTRegistry<T> { List: List<T> }

然后你可以像这样使用它:

const f = <A extends HKT, B>(a: Specify<A, B>, b: B): [Specify<A, B>, B] => [a, b];

const id = f<"Id", number>(1, 2);
const hmm = f<"List", number>([1], 2);

其中 HKTSpecify 的定义如下:

type HKT = keyof HKTRegistry<any>
type Specify<H extends HKT, T> = HKTRegistry<T>[H];

Playground link to code

但它很笨重,并且不能捕获 constrained 类型参数之类的东西,而且很难以这种方式推断 HKT。正如我所说,它并不是我真正推荐用于任何生产代码的地方。

相关问题