TypeScript 中的高阶类型函数?

brn*_*csk 8 generics nested-generics open-generics typescript

请考虑以下尝试使用函数类型参数定义高阶类型函数的伪代码M<?>

type HigherOrderTypeFn<T, M<?>> = T extends (...)
  ? M<T>
  : never;
Run Code Online (Sandbox Code Playgroud)

M<?>是语法错误的 TypeScript,但将类型签名声明为会在第二行HigherOrderTypeFn<T, M>产生错误Type 'M' is not generic. ts(2315)

假设这种类型目前在 TS 中无法表示,我是否正确?

jca*_*alz 8

你是对的,它目前无法在 TypeScript 中表示。有一个长期开放的 GitHub 功能请求microsoft/TypeScript#1213,它的标题可能应该是“支持更高级的类型”,但目前的标题是“允许类在其他参数类中具有参数”。

关于如何在当前语言中模拟这种更高级的类型的讨论中有一些想法(有关具体示例,请参阅此评论),但在我看来,它们可能不属于生产代码。如果您有一些要实施的特定结构,也许可以建议一些合适的内容。

但是在任何情况下,如果您想增加这种情况发生的可能性(可能可以忽略不计,不幸的是),如果您认为与什么已经在那里了。好的,希望有帮助;祝你好运!

  • 这个讨论让我觉得未来的编程语言会很像 Haskell...... (2认同)

Rem*_*ror 8

对于您和其他正在寻找解决方法的人来说,您可以尝试一个基于占位符的简单想法(请参阅jcalz 提到的讨论中的此评论):

type Placeholder = {'aUniqueKey': unknown};
type Replace<T, X, Y> = {
  [k in keyof T]: T[k] extends X ? Y : T[k];
};
Run Code Online (Sandbox Code Playgroud)

因此,您的函数将如下所示:

type HigherOrderTypeFn<T, M> = T extends (...) ? Replace<M, Placeholder, T> : never;
Run Code Online (Sandbox Code Playgroud)

并被这样称呼:

type M<U> = U[];
type X = HigherOrderTypeFn<number, M<Placeholder>> // is number[] (if ... is number)
Run Code Online (Sandbox Code Playgroud)