typescript - 使 TypeScript 推断高阶函数的模板参数

标签 typescript generics types inference

我有一些非常简单的函数,它接收函数和参数并使用该参数执行函数。 我写过这样的代码:

type Action<Payload> = (payload: Payload) => any;

type SomeType = string;

declare function execute<Payload>(action: Action<Payload>, payload: Payload);

declare function testFn<P extends SomeType>(payload: P): number;

execute(testFn, '');

run in typescriptlang.org repl

但它会产生错误:

Argument of type '<P extends string>(payload: P) => number' is not assignable to parameter of type 'Action<{}>'.
  Types of parameters 'payload' and 'payload' are incompatible.
    Type '{}' is not assignable to type 'string'.

事实是,如果我更改参数的顺序,它会使 typescript 正确推断类型:

type Action<Payload> = (payload: Payload) => any;

type SomeType = string;

declare function execute<Payload>(payload: Payload, action: Action<Payload>);

declare function testFn<P extends SomeType>(payload: P): number;

execute('hell yeah!', testFn);

run in typescriptlang.org repl

有没有办法在不改变顺序的情况下让它工作?为什么 typescript 总是尝试从左到右推断类型?

更新:

它似乎在 TypeScript 本身中缺失了一部分:

PR with this feature added

same question on Github

huge discussion on the topic

最佳答案

这是一个有趣的问题。在尝试了一下之后,我想我找到了一个具有正确行为的签名:

declare function execute<P>(action: Action<any> & Action<P>, payload: P): void;

交集类型似乎延迟了 Action<P> 的评估直到P之后已推断:

execute(testFn, '');  // okay
execute(testFn, 123);  // error, 123 is not a string

我真的不知道为什么会这样(也许更熟悉编译器内部的人可以在这里说些更好的话)但也许这足以帮助你取得进步?祝你好运!

关于typescript - 使 TypeScript 推断高阶函数的模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53359719/

相关文章:

typescript - 如何调试 Electron-Forge React-TypeScript 的渲染器进程?

c# - 覆盖 StructureMap 3 中的自定义注册约定

c# - 为什么将基类分配给派生类需要显式转换?但不需要做相反的事情

javascript - 当我们从 Angular Material 垫菜单中选择任何项目时,焦点将从元素中移除

javascript - 添加新项目时 vsCode 刷新树

typescript - typescript 3.33的onClick问题并使用react

json - 使用 Aeson/JSON 自动派生自定义数据类型的实例

c# - 通用列表/子列表处理

python - range() 中的计数器未被识别为整数

java - Node 缓冲区打印问题