请考虑下面的伪代码,它试图定义一个高阶类型函数,该函数具有函数类型的参数M<?>
:
type HigherOrderTypeFn<T, M<?>> = T extends (...)
? M<T>
: never;
M<?>
在语法上是不正确的TypeScript,但将类型签名声明为HigherOrderTypeFn<T, M>
会在第二行产生错误Type 'M' is not generic. ts(2315)
。
我假设这样一种类型目前在TS中是无法表示的,对吗?
请考虑下面的伪代码,它试图定义一个高阶类型函数,该函数具有函数类型的参数M<?>
:
type HigherOrderTypeFn<T, M<?>> = T extends (...)
? M<T>
: never;
M<?>
在语法上是不正确的TypeScript,但将类型签名声明为HigherOrderTypeFn<T, M>
会在第二行产生错误Type 'M' is not generic. ts(2315)
。
我假设这样一种类型目前在TS中是无法表示的,对吗?
4条答案
按热度按时间qvtsj1bj1#
你是对的,它目前无法在TypeScript中表示。有一个长期开放的GitHub功能请求,microsoft/TypeScript#1213,它可能应该被命名为“支持更高类型”,但目前的标题是“允许类在其他参数类中参数化”。
在讨论中有一些关于如何在当前语言中模拟这种高级类型的想法(具体示例请参阅此评论),但在我看来,它们可能不属于生产代码。如果您有一些特定的结构要实现,也许可以建议一些合适的东西。
但在任何情况下,如果你想增加这种情况发生的可能性(不幸的是,可能可以忽略不计),你可能想去那个问题,并给予它一个👍和/或描述你的用例,如果你认为它与已经存在的情况相比特别引人注目。!
rdrgkggo2#
对于你和其他正在寻找解决方法的人来说,你可以尝试一个基于占位符的简单想法(请参阅jcalz提到的讨论中的评论):
因此,您的函数看起来如下所示:
并被称为这样的例子:
798qvoo83#
对于遇到这个问题的人来说,在TypeScript discord服务器上有一个很好的例子:
其可以如下使用。下面的代码片段定义了一个
SetFactory
,在创建工厂时,您可以在其中指定所需的set类型,例如typeof FooSet
或typeof BarSet
。typeof FooSet
是FooSet
的构造函数,类似于更高级的kinded类型,构造函数类型接受任何T
并返回FooSet<T>
。SetFactory
包含几个方法,如createNumberSet
,它返回一个给定类型的新集合,类型参数设置为number
。简单解释一下它是如何工作的(以
FooSet
和number
为例):Hkt.Output<Const["hkt"], T>
。替换了我们的示例类型后,它变成了Hkt.Output<(typeof FooSet)["hkt"], number>
。现在的魔术是将其转换为FooSet<number>
(typeof FooSet)["hkt"]
到FooSetHkt
。这里有很多神奇的地方,通过将有关如何创建FooSet
的信息存储在FooSet
的静态hkt
属性中。您需要为每个支持的类执行此操作。Hkt.Output<FooSetHkt, number>
。解析Hkt.Output
类型别名,我们得到(FooSetHkt & { [Hkt.input]: number })[typeof Hkt.output]
。唯一的符号Hkt.input
/Hkt.output
有助于创建唯一的属性,但我们也可以使用唯一的字符串常量。FooSetHkt
的Hkt.output
属性。这对于每个类都是不同的,并且包含了如何用类型参数构造具体类型的细节。FooSetHkt
将output属性定义为FooSet<Hkt.Input<this>>
类型。Hkt.Input<this>
只访问FooSetHkt
的Hkt.input
属性。它将解析为unknown
,但通过使用交集FooSetHkt & { [Hkt.input]: number }
,我们可以将Hkt.input
属性更改为number
。因此,如果我们达到了目标,Hkt.Input<this>
将解析为number
,FooSet<Hkt.Input<this>>
将解析为FooSet<number>
。对于问题中的例子,
Hkt.Output
本质上是所要求的,只是类型参数颠倒了:xqk2d5yq4#
在fp-ts中有一个HKT(利用模块增强)的实现。
高Kinded类型as documented here by its author的解决方法是:
可以这样使用:
看看这个问题:higher kinded type in typescript from fp-ts and URI
也许这能提供一些线索
干杯