创建通用 TypeScript 函数,为对象属性赋值

2023-11-29

我想创建一个简单的函数key特定对象的和value为相应的键并将新值分配给对象。像这样的东西:

interface MyObject {
    key1: string
    key2: number
}

const object: MyObject = {
    key1: 'abc',
    key2: 100
}

const updateObjectProperty = (key: keyof MyObject, value: MyObject[keyof MyObject]) => {
    object[key] = value
}

但在这种情况下 - 它不起作用。 TypeScript 编译器显示错误:

Type 'string | number' is not assignable to type 'never'.

我觉得也许一些仿制药可以解决这里的问题,但我正在努力弄清楚如何解决。


如果使用泛型类型参数将参数绑定在一起,它将编译:

const updateObjectProperty = <K extends  keyof MyObject>(key: K, value: MyObject[K]) => {
    object[key] = value
}

updateObjectProperty("key1", "") //ok
updateObjectProperty("key2", "") // err
updateObjectProperty("key2", 2) // ok

游乐场链接

您的版本不起作用的原因是您可以传递不相关的键和值:

updateObjectProperty("key2", "") // key2 now has a string

游乐场链接

现在我们的新版本也不是100%安全,你可以这样调用它keyunion,但这种情况不太常见:


let k: keyof MyObject = Math.random() > 0.5 ? "key1" : "key2"
let v: MyObject[keyof MyObject] = Math.random() > 0.5 ? 0 : "key2"

updateObjectProperty(k, v); // fails when key and value are mssmatched

游乐场链接

您可以执行与 TS 相同的操作,并将 value 作为可能的属性值的交集键入,这也将捕获此漏洞,但这将需要在实现中再次断言:

type ValueIntersectionByKeyUnion<T,  TKey extends keyof T> = {
  [P in TKey]: (k: T[P])=>void
} [TKey] extends ((k: infer I)=>void) ? I : never

const updateObjectProperty = <K extends  keyof MyObject>(key: K, value: ValueIntersectionByKeyUnion<MyObject, K>) => {
    object[key] = value as MyObject[K];
}

let k: keyof MyObject = Math.random() > 0.5 ? "key1" : "key2"
let v: MyObject[keyof MyObject] = Math.random() > 0.5 ? 0 : "key2"

updateObjectProperty(k, v); //err

updateObjectProperty("key1", "") //ok
updateObjectProperty("key2", "") // err
updateObjectProperty("key2", 2) // ok

游乐场链接

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

创建通用 TypeScript 函数,为对象属性赋值 的相关文章

随机推荐

  • 使用 dplyr 按多组进行汇总

    我正在尝试使用 dplyr 来总结基于 2 个组的数据集 年份 和 区域 数据集如下所示 Year Area Num 1 2000 Area 1 99 2 2001 Area 3 85 3 2000 Area 1 60 4 2003 Are
  • 使用 window.onscroll 事件检测页面/框架滚动

    我想定位一个DIV位于页面内 以便即使用户垂直滚动页面 用户也可以看到它 该页面的顶部有一个标题 即75 px高的 现在 当用户位于页面顶部并且没有垂直滚动时 DIV必须位于标题下方 然而 一旦用户滚动页面导致标题消失 同样的DIV现在必须
  • 如何在 PHP 中检查 PDF 文件是否受密码保护 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 使用 PHP 上传多个文件时 如何检查上传的 PDF 文件是否受密码保护 如果它
  • java中如何将时间戳转换为日期和时间?

    我有一个来自 Linux 服务器的 json 时间戳 我想使用 Java 将其转换为简单的日期时间格式 我需要以下格式的日期和时间 dd mm yyyy hh mm ss 这是我的 JSON 数据 batch date 1419038000
  • 同步push_back和std::thread

    My code void build std vector
  • Symfony2 从 api 数据填充选择列表

    我必须通过 Api 调用填充选择列表 我尝试了几种方法但没有成功 我认为最好的方法是实现 ChoiceListInterface 有人已经做到了吗 Thanks Extend 惰性选择列表并实施加载选择列表方法 例如 ApiChoiceLi
  • 复制 Excel 单元格数据直到列中最近的填充单元格

    我是 Excel 的新手 我面临一些问题 我有一个 Excel 工作表 必须将其导入到我的另一个程序中 请考虑以下格式 Heading1 Sub heading1 Sub Sub heading1 Sub Sub heading2 Sub
  • Ruby 数组注入

    我试图使用注入方法记录 10 个线程的平均运行时间 但它给了我这个错误 undefined method for
  • 将文件从 URL 传输到 Cloud Storage

    我是一名 Ruby 开发人员 尝试使用 Python 编写的 Google Cloud Functions 但在将远程文件从给定 URL 传输到 Google Cloud Storage GCS 时遇到了困难 在等效的 RoR 应用程序中
  • 如何使用 android.mk 将 .aar 包含在 AOSP 中

    我需要在 aosp 构建树中使用 android mk 构建一个应用程序 我有一个自定义的 arr lib 它位于以下文件夹 apps libs mylib aar 中 任何人都可以告诉我如何将 aar 包含在 android aosp 构
  • 将“工作集”装入 MongoDB 的 RAM 意味着什么?

    MongoDB 很快 但前提是您的工作集或索引可以放入 RAM 那么 如果我的服务器有 16G RAM 这是否意味着我所有集合的大小都需要小于或等于 16G 如何说 好吧 这是我的工作集 其余的可以 存档 工作集 基本上是系统将处于活动状态
  • MVC模型验证

    因此 我当前正在构建一个需要用户模型验证的应用程序 如果向用户填写了不正确的属性 它会告诉他们 我已设置数据注释 但我不确定如何将错误消息转发回用户 到目前为止 我已经在我的模型和视图上进行了设置 Model public class Da
  • setNamedRange() 在电子表格容器之外?

    我已经尝试了尽可能多的组合 我的目标是让 Google Apps 脚本独立运行或从库中运行 并能够在电子表格中设置命名范围 据我所知 setNamedRange 方法仅在电子表格容器内可用 并且仅当您使用SpreadsheetApp get
  • Teams:Invoke-Webrequest 向 Teams 发送 base64 字符串 (png)

    我正在尝试将一个 png 格式的 base64 字符串发送到我们的团队频道 该频道具有 传入 Webhook 设置 消息已发送到频道 但没有显示图像 当我搜索此内容时 似乎无法将图像或任何其他类型的附件作为 base64 字符串发送到 Te
  • 在python中动态添加@property

    我知道我可以通过执行以下操作动态地将实例方法添加到对象 import types def my method self logic of method instance is some instance of some class inst
  • Win32 GUI 在调整大小时闪烁

    我有一个带有选项卡控件的 Win32 GUI 程序 每个选项卡都有一个列表视图控件 每当调整窗口大小时都会出现大量闪烁 我尝试过以下操作 在主 wndproc 中处理 WM ERASEBKGND 并返回 TRUE 没有效果 过滤掉事件循环中
  • 当UAC打开时,程序可以在没有管理员权限的情况下写入磁盘的根目录吗?

    如果我不是管理员并启动一个写入 C 某些文本文件的程序 在 Windows 7 或 Vista 中我是否需要管理员权限 我发现在 XP 中写入任何文件夹 包括 system32 都没有问题 但我不确定 NET 中的程序是否能够在没有管理员权
  • 与文本字段和日期选择器相关的问题

    我有一个与单击文本字段时隐藏和显示日期选择器视图相关的问题 实际上我有 2 个文本字段 这是我的问题图像 Problem 单击文本字段时日期选择器显示和隐藏 它应该在开始编辑时显示并在结束编辑时隐藏 当我们第一次点击 textfield 1
  • 在 LinearLayout 中动态创建多个 TextView

    我想创建多个TextView里面有一个LinearLayout 以下代码构建成功 但给出了NullPointerException在线上root addView t i public class MainActivity extends A
  • 创建通用 TypeScript 函数,为对象属性赋值

    我想创建一个简单的函数key特定对象的和value为相应的键并将新值分配给对象 像这样的东西 interface MyObject key1 string key2 number const object MyObject key1 abc