如何在 TypeScript 中为对象动态分配属性

介绍

考虑以下示例:

const organization = {}
organization.name = "Logrocket"                                                                                 

这段看似无害的代码在动态分配时会引发 TypeScript 错误 name到 organization目的。

将属性动态分配给对象时引发错误

中的此示例 请参阅TypeScript Playground 。

如果您是 TypeScript 初学者,这也许是正确的,混淆的根源是:看起来如此简单的东西怎么会在 TypeScript 中成为这样的问题?

TL;DR 的全部内容是,如果你不能在声明时定义变量类型,你可以使用 Record实用程序类型或对象索引签名来解决这个问题。 但在这篇文章中,我们将探讨问题本身,并努力寻找在大多数情况下都可以使用的解决方案。

跳跃前进:

  • 了解将属性动态分配给对象的问题

  • 解决问题

    • 解决方案 1:在声明时显式键入对象

    • 解决方案 2:使用对象索引签名

    • 解决方案 3:使用 Record实用类型

了解将属性动态分配给对象的问题

一般来说,TypeScript 在声明变量时确定变量的类型,并且该确定的类型不会改变,即在整个应用程序中始终保持不变。

此规则有一些例外情况,例如在考虑缩小类型或使用 any类型,但这是要记住的一般规则。

在前面的例子中, organization对象声明如下:

const organization = {}

没有明确的类型分配给 organization变量,所以 TypeScript 推断出一个类型 organization根据声明 {},即文字空对象。


超过 20 万开发人员使用 LogRocket 来创造更好的数字体验 了解更多 →


例如,如果您添加一个类型别名,您可以探索的类型 organization:

type Org = typeof organization

探索字面量对象类型

请在 TypeScript Playground 中查看。

然后,当您尝试引用 name支持这个空对象文字:

organization.name = ...

TypeScript 大喊。

类型 ' 上不存在属性 'name' {}‘

当您了解问题时,该错误似乎确实合适。

让我们解决这个问题。

解决问题

有很多方法可以在这里解决 TypeScript 错误。 让我们考虑这些:

解决方案 1:在声明时显式键入对象

这是推理的最简单的解决方案。 在您声明对象时,请继续输入它。 此外,为其分配所有相关值。


来自 LogRocket 的更多精彩文章:

  • 不要错过 The Replay 来自 LogRocket 的精选时事通讯

  • 了解 LogRocket 的 Galileo 如何消除噪音以主动解决应用程序中的问题

  • 使用 React 的 useEffect 优化应用程序的性能

  • 之间切换 在多个 Node 版本

  • 了解如何 使用 AnimXYZ 为您的 React 应用程序制作动画

  • 探索 Tauri ,一个用于构建二进制文件的新框架

  • 比较 NestJS 与 Express.js


type Org = {
    name: string
}
​
const organization: Org = {
    name: "Logrocket"
}

请在 TypeScript Playground 中查看。

这消除了任何意外。 您清楚地说明了此对象类型是什么,并在创建对象时正确声明了所有相关属性。

但是,如果必须 动态 添加对象属性,这并不总是可行的,这就是我们都在这里的原因。

解决方案 2:使用对象索引签名

有时,对象的属性确实需要在声明后一次添加。 在这种情况下,您可以使用对象索引签名,如下所示:

type Org = {[key: string] : string}
const organization: Org = {}
organization.name = "Logrocket"

请在 TypeScript Playground 中查看。

当时的 organization变量已声明,您可以继续并将其显式键入以下内容 {[key: string] : string}.

为了进一步解释语法,您可能习惯于具有固定属性类型的对象类型:

type obj = {
  name: string
}

但是,您也可以替换 name对于“变量类型”。

例如,如果你想定义任何字符串属性 obj:

type obj = {
 [key: string]: string
}

请注意,语法类似于您在标准 JavaScript 中使用变量对象属性的方式:

const variable = "name" 
const obj = {
   [variable]: "Freecodecamp"
}

TypeScript 等效项称为对象索引签名。 此外,请注意,您可以键入 key与其他原语:

// number 
type Org = {[key: number] : string}
​
// string 
type Org = {[key: string] : string}
​
//boolean
type Org = {[key: boolean] : string}

解决方案 3:使用 Record实用类型

这 Record实用程序类型 允许您限制其属性为的对象类型 Keys和属性值是 Type. 它具有以下签名: Record<Keys, Type>.

在我们的示例中, Keys代表 string和 Type, string也是。 这里的解决方案非常简洁,如下所示:

type Org = Record<string, string>
​
const organization: Org = {}
​
organization.name = "Logrocket"

除了使用类型别名,您还可以内联类型:

const organization: Record<string, string> = {}

使用 Record实用类型

请在 TypeScript Playground 中查看。

大师兄影视App,支持双端影视追剧,多源播放支持投屏!

结论

除了原语之外,您必须处理的最常见的类型可能是对象类型。   如果您需要动态构建对象,请利用 Record实用程序类型或使用对象索引签名来定义对象上允许的属性。

如果您想了解更多关于这个主题的信息,请随时 查看我 的备忘单,了解 Stack Overflow 上的七个最常见的 TypeScript 问题,或者向 我发送任何问题 。 干杯!

写了很多 TypeScript? 观看 我们最近的 TypeScript 聚会的录像,了解如何编写更具可读性的代码。

TypeScript 为 JavaScript 带来了类型安全。 类型安全和可读代码之间可能存在紧张关系。 观看录音,深入了解 TypeScript 4.4 的一些新功能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pxr007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值