Typescript 无法推断函数对象的正确参数类型

2023-12-03

我写了一个更新函数,它接受一个对象,T,以及一个“更新程序”对象,它采用与以下相同的键(或子集)T并提供更新原对象对应值的函数。

type UpdaterObj<T> = {
    [K in keyof Partial<T>]: (t: T[K]) => T[K]
};
declare function update<T>(obj: T, updaterObj: UpdaterObj<T>): T

示例用法如下:

const foo = {
    x: 1,
    y: "1"
};

update(foo, {
    x: (xx: number) => xx + xx,
    y: (yy: string) => yy + yy,
}); // Result is { x: 2, y: "11" }

这可行,但我真的想删除这些注释并只写x: (xx) => xx + xx and y: (yy) => yy + yy,但是我得到了Parameter implicitly has type 'any'错误,对于两者xx and yy.

这很奇怪,因为如果我将鼠标悬停在x:,它正确地推断出相应的值应该是什么,但是,如果我注释它它会抱怨xx or yy作为错误的类型,而且我很确定我以前见过打字稿做出类似的推论。

在这种情况下,注释非常简单,但如果我深入对象或更复杂的类型,注释可能会变得烦人,因此推理在这里非常有帮助。

对我的定义或用法是否有任何简单的调整,可以让打字稿为我推断这一点?


我不确定是否存在问题GitHub关于函数参数的类型推断如何与泛型类型参数的推断交互,所以我不知道是否对函数签名进行了简单的调整,使其可以在不影响调用站点的情况下工作。

看着TypeScript 规范,我看到对于 TypeScript 函数表达式(例如xx => xx + xx),

当没有类型参数且没有参数类型注释的函数表达式由类型根据上下文类型化时T 和上下文签名S可以从中提取T,函数表达式的处理就好像它具有显式指定的参数类型注释一样,因为它们存在于S.

[snip]

上下文签名S从函数类型中提取T如下:

  • If T是一种只有一个调用签名的函数类型,并且如果该调用签名是非通用的, S是那个签名。

  • If T是联合类型... [剪断]

  • 否则,无法从中提取上下文签名T.

所以看起来好像是因为(xx => xx + xx)在您的原始调用中具有以下形式的函数类型(t: T['x']) => T['x']包括类型参数T,它不会像处理具有显式类型参数那样处理该函数。据推测,这意味着编译器在消除通用参数之前尝试提取上下文签名。


如果可以更改调用站点,那么我可以提出的最简单的建议(明显有效)就是打破两个参数update()函数变成curried函数如下:

declare function updateCurried<T>(obj: T): (updaterObj: UpdaterObj<T>) => T

其使用方式如下(注意函数调用的顺序):

updateCurried(foo)({
  x: xx => xx + xx,
  y: yy => yy + yy,
}); // okay

这实质上迫使编译器在评估泛型类型参数时评估并消除泛型类型参数。updaterObjprarameter,此时它可以进行上下文函数参数推断,如上面规范摘录中所述。

希望这对您有帮助。祝你好运!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Typescript 无法推断函数对象的正确参数类型 的相关文章

随机推荐

  • 捕获 xsl 结果文档的输出流

    我需要一种方法来干扰写入 xsl 结果文档 以避免将它们写入文件系统 现在我的模板正在写入临时目录 然后我压缩该目录 我想在不写入文件系统的情况下执行此操作 我正在使用 saxon 处理器 首选仅使用标准 java 库的解决方案 任何建议表
  • 如何在 Eclipse 中使用点(DOTALL)匹配多行查找正则表达式

    我想转换这个 def getEmployeeReminders employeeId Int page Option Int pageSize Option Int js callback Option String Action val
  • Pine 脚本 (TradingView) - 如何将止损移至获利水平

    TradingView 上有一个 Pine 脚本代码 其中有 2 个止盈水平和 2 个止损水平 交易视图网 当实现第一个止盈时 一半仓位被平仓 第一个止损移至入场水平 盈亏平衡 您是否有任何想法如何通过以下逻辑设置 3 个止盈水平 当达到
  • 函数替换子字符串返回错误答案

    我有一个程序替换字符串中的子字符串 我们的想法是找到string to be replaced in original string then realloc the new string并将其连接到replace by细绳 它适用于某些情
  • Android开发:以root权限以编程方式禁用“显示通知”?

    有没有办法以编程方式更改应用程序的详细信息 设置 gt 应用程序 gt anApp 具体来说 我可以取消选中 显示通知 吗 我假设你有root权限 预先感谢您的帮助 首先 这似乎取决于您对哪个版本的 Android 感兴趣 似乎 4 3 中
  • 我们可以使用 Selenium webdriver 来自动化基于 MS CRM 2015 的应用程序吗?

    我们可以使用 Selenium webdriver 来自动化基于 MS CRM 2015 的应用程序吗 如果不能 是否有任何具体原因 如果网页基于 HTML Selenium 可以自动化网页的任何部分 因此 如果您想检查它 请打开 CRM
  • 使用 Spring MVC 和 Boot 刷新静态内容

    我正在评估 Spring MVC Boot 和 AngularJs 用于构建 Web 应用程序 我遇到了这样的问题 当我修改静态内容 html js css 时 我每次都必须重新启动应用程序 我希望有某种方法可以解决这个问题 因为重新启动整
  • Application Insights 不捕获信息级别日志记录

    我有一个简单的 Asp Net Core Web API 应用程序 对于这个例子 我遵循了这里的官方文档 https learn microsoft com en us azure azure monitor app asp net cor
  • 使用VBA和数组公式方法进行多条件VLookup

    因此 当需要在 VBA 中创建具有多个条件的 VLookUp 时 我们的想法是利用漂亮的数组公式方法及其背后的想法 问题 我们可以将其翻译成VBA吗 INDEX range1 MATCH 1 A1 range2 B1 range3 C1 r
  • Python 排列下没有相同元素的集合的笛卡尔积

    我有一些集合 我想对其进行笛卡尔积 效果很好 但是 我想删除这个新集合中在元素排列下相同的所有元素 例如 采用以下代码 import itertools as ittools x 2 y 3 z 5 flist list ittools p
  • DocumentDB 子查询

    我正在尝试从包含双重嵌套数组的大型文档投影到数组的扁平表示中 但我不知道如何继续 我有类似这样的文件 id 1 themeId e4d3549c 2785 4067 83d6 f396d2212776 enabled false archi
  • .NET Compact 框架 - 使滚动条更宽

    有什么方法可以使 net 紧凑框架的 winforms 中的滚动条更宽吗 我希望应用程序对手指友好 但对于手指不小的人来说 滚动条非常窄 EDIT 问题出在 ListView DataGrid 等组件中的内置滚动条 Windows Mobi
  • 如何在 XAMPP 中将 MariaDB 更改为 MySQL?

    A 首先要做的事情 Google 先生没有帮助我找到任何对我的问题的答复 多于 是的 我在这里阅读了相反问题的解决方案如何在 Windows 上 5 分钟内将 XAMPP 中的 MySQL 升级到 MariaDB 这对我没有帮助 MySQL
  • 从远程服务器运行 jupyter 笔记本的脚本

    我有一台运行 jupyter 笔记本的服务器 Ubuntu 服务器 16 04 以及一台本地计算机 Mac 我在其中使用 google chrome 来可视化这些笔记本 为此 我必须 在服务器中运行 jupyter Notebook jup
  • RegEx 字符串查找两个字符串并删除文件中其余文本

    我需要用记事本 查找并删除文本文件中的其余部分 我希望你使用 RegeX 来查找 thban 的变体 该变量后面始终最多有 5 个字符 参见点 使用我的搜索字符串 它击中了最后一行 但击中了整行 我只想保留这个词 当这有效时 我也想保留包含
  • 无法使用 Facebook Marketing API 获取暂停的广告见解

    我编写了这个脚本 该脚本返回广告列表及其统计信息 但显然我只获得了活动广告的见解 而不是暂停的广告 对于暂停的广告 我只是获得了广告活动名称及其 id 我尝试使用如下所示的过滤 但它不起作用 first https graph facebo
  • 如何使用 Spring Data JPA 规范创建自定义查询? [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 在我的 Spring Boot 应用程序中 我使用 JPA 规范创建了自定义过滤 如上所述使用 JPA 规范搜索和过滤 Spring Boot 但是 我需要连接多个表并构建一个W
  • 如何修复此 SQL 插入语句中的语法错误?

    第一次在这里发布海报 我正在 VBA Access 数据库 中创建 SQL 插入语句 但当我最终准备好通过我创建的表单进行插入时 我不断收到语法错误 似乎无法弄清楚我在这个声明中出了什么问题 因为过去同样的格式对我有用 我在论坛上寻找已经回
  • MUI 依赖错误 npm install @mui/icons-material

    npm install mui icons material npm ERR code ERESOLVE npm ERR ERESOLVE unable to resolve dependency tree npm ERR npm ERR
  • Typescript 无法推断函数对象的正确参数类型

    我写了一个更新函数 它接受一个对象 T 以及一个 更新程序 对象 它采用与以下相同的键 或子集 T并提供更新原对象对应值的函数 type UpdaterObj