TypeScript 是否可以从动态对象推断键?

2024-06-23

我在这里想要实现的是从数组生成的对象的智能感知/自动完成 - 类似于 Redux 的 Action Creator,一个字符串数组(string[])可以简化为具有形状的对象{ [string]: string }.

例如:

const a = ['ONE', 'TWO', 'THREE'];

const b = a.reduce((acc, type) => ({ ...acc, [type]: type }), {});

console.log(b);
// Output: b = { ONE: 'ONE', TWO: 'TWO', THREE: 'THREE' };

我已经使用下面的内容成功地让 TypeScript 理解了这一点。 TypeScript 知道键是字符串,但不知道它们是什么。

interface ITypesReturnObject { [s: string]: string }

有没有人想出一种方法来通知 TypeScript 对象上的键等于数组中的字符串?

任何帮助将不胜感激。


(以下假设您使用TS3.0或更高版本)

TypeScript 支持以下概念字符串文字类型 https://www.typescriptlang.org/docs/handbook/advanced-types.html#string-literal-types元组类型 https://www.typescriptlang.org/docs/handbook/basic-types.html#tuple,这样就有可能得到你的值a拥有type ['ONE', 'TWO', 'THREE']以及value ['ONE', 'TWO', 'THREE'], 像这样:

const a: ['ONE', 'TWO', 'THREE'] = ['ONE', 'TWO', 'THREE'];

(稍后将提供一种不太冗余的方法来实现这一点):

然后你可以代表想要的类型b作为从键到与键完全匹配的值的映射,使用映射类型 https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped-types:

type SameValueAsKeys<KS extends string[]> = { [K in KS[number]]: K };

可以这样使用:

const b: SameValueAsKeys<typeof a> = a.reduce((acc, type) => ({ ...acc, [type]: type }), {} as any);
b.ONE; // property type is "ONE"
b.TWO; // property type is "TWO"
b.THREE; // property type is "THREE"

注意编译器如何知道这一点b有三把钥匙,"ONE", "TWO", and "THREE",并且值与键相同。


所以 TypeScript 当然支持这种类型的动态类型。不幸的是,正如我上面展示的那样,使用起来有点乏味。减少这种烦恼的一种方法是添加一些辅助函数,允许编译器推断正确的类型,或者至少将类型断言隐藏在库中,开发人员不必担心它们。

首先,对于a...编译器不会推断元组类型,并且它也倾向于将字符串文字扩大到string键入除某些情况 https://github.com/Microsoft/TypeScript/pull/10676。让我们引入一个名为的辅助函数stringTuple():

function stringTuple<T extends string[]>(...args: T) { return args; }

这推断出一个来自剩余参数的元组类型 https://github.com/Microsoft/TypeScript/wiki/What's-new-in-TypeScript#tuples-in-rest-parameters-and-spread-expressions。现在我们可以用它来制作a无需输入多余的字符串值:

const a = stringTuple("ONE", "TWO", "THREE");

接下来,让我们介绍一个函数,它接受字符串列表并返回一个对象,该对象的键是这些字符串,并且其值与字符串匹配:

function keyArrayToSameValueAsKeys<T extends string[]>(keys: T): SameValueAsKeys<T>;
function keyArrayToSameValueAsKeys(keys: string[]): { [k: string]: string } {
  return keys.reduce((acc, type) => ({ ...acc, [type]: type }), {});
}

在这里,我们使用与您相同的代码reduce,但我们将它隐藏在它自己的函数中并使用单个重载调用签名 https://www.typescriptlang.org/docs/handbook/functions.html#overloads来表示预期的输出类型。现在,我们可以得到b像这样:

const b = keyArrayToSameValueAsKeys(a);
b.ONE; // property type is "ONE"
b.TWO; // property type is "TWO"
b.THREE; // property type is "THREE"

如果你把stringTuple() and keyArrayToSameValueAsKeys()在库中,用户可以毫不费力地使用它们:

const otherObject = keyArrayToSameValueAsKeys(stringTuple("x", "y", "z"));
// const otherObject: {X: "X", Y: "Y", Z: "Z"}

或者你可以像这样将它们合并在一起:

function keysToSameValueAsKeys<T extends string[]>(...keys: T): { [K in T[number]]: K };
function keysToSameValueAsKeys(keys: string[]): { [k: string]: string } {
  return keys.reduce((acc, type) => ({ ...acc, [type]: type }), {});
}

然后通过一次调用获取输出,如下所示:

const lastOne = keysToSameValueAsKeys("tic", "tac", "toe");
// const lastOne: {tic: "tic", tac: "tac", toe: "toe"};

好的,希望对您有所帮助。祝你好运!

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

TypeScript 是否可以从动态对象推断键? 的相关文章

  • Webpack、Sass - 超出最大调用堆栈大小

    我正在为我的 JS 应用程序使用 Webpack 对于样式 我使用 Sass 我的应用程序非常大 所以我使用了很多 mixins 和 includes 在过去的几天里 虽然应用程序的 SASS 数据增长了一些 我多次遇到相同的以下错误 未捕
  • 如何捕获jquery中的任何点击事件[重复]

    这个问题在这里已经有答案了 我有一个按钮 当单击它时 会显示一个带有图像的 div 例如聊天的表情符号面板 如果我再次单击它 div 会隐藏 但我想要做的是 如果 div 已经显示 然后我单击页面的任何其他内容 我想隐藏它 我试过这个 my
  • React - useState 的 setter 函数可以改变吗?

    useState 的 setter 是否能够在组件生命周期内更改 例如 假设我们有一个useCallback这将更新状态 如果 setter 能够更改 则必须将其设置为回调的依赖项 因为回调使用它 const state setState
  • 如何使用React Native在屏幕上绘图?

    我正在尝试在 React Native 中实现一个 Android 绘图应用程序 我正在使用 PanResponder 但我不知道如何获取用户触摸的部分的坐标 我尝试过使用react native svg但我不知道该放在哪里PanRespo
  • 使用 mongoDB 插入子文档

    我收集了以下文件 id 2 workspace name 1 widgets name 2 widgets name 3 widgets name 4 widgets 我怎样才能插入 id 1 blabla blabla 在 小部件 中的
  • jQuery:“$(this).next().next()”有效,但“$(this).next('.div')”无效

    好吧 我正在尝试将这组信息单独隐藏 这有效 arrow click function this next next slideToggle img class arrow src https via placeholder com 40 h
  • 通过标记或JS强制下载

    假设我在 CDN 来自 Rackspace 的云文件 上有一个文件 以及一个包含该文件链接的静态 html 页面 有什么方法可以强制下载此文件 以防止它在浏览器中打开 例如 mp3 我们可以让我们的服务器读取该文件并将相应的标头设置为 he
  • 滚动动态数据时,React Native“onViewableItemsChanged”不起作用

    我有一个 React Native FlatList 基于文档 https facebook github io react native docs flatlist html onviewableitemschanged I used o
  • 在 Bootstrap 选择器上使用 jQuery 取消选择选项

    我对一些 UI 元素使用 Bootstrap SelectPicker 它允许用户选择多个选项并将其呈现在段落标签中的屏幕上 他们还应该能够删除选定的选项 这是我的代码 用于将选定的选项渲染到屏幕上 以便每个选项旁边都会显示一个 X 单击它
  • 如何更改 nx 应用程序的 ts 路径别名

    我正在将现有应用程序导入 NX monorepo 其文件结构与默认应用程序略有不同 它看起来像这样 apps my app src feature 1 feature 2 main components my component tsx i
  • LightningChart JS - LineSeries / Progressive X 的损坏

    我在使用 LightningChart 时遇到了一个有趣的问题 它似乎会破坏或以其他方式减少我的数据 具体取决于它与图表的 DateOrigin 的距离 我的数据是每秒 1000 个样本 我试图一次显示 1 2 周的数据 我正在使用 Cha
  • 在 ReactJS 中更改 URL onClick

    在我的项目中我有一个TabComponent它显示 3 个选项卡 首页 热门 全部 现在 我正在使用context反应维持 activetab它存储当前选项卡 toggleTab改变的方法activetab using setState 选
  • 过滤数据表中的行

    我目前的 JQuery 插件 DataTables 工作正常 并且我在页面顶部插入了一个按钮来进一步过滤列表 我还使用了 DataTables 内置的搜索栏 我希望按钮向下过滤表格 并只显示包含特定值的行 下面是我一直在做的事情 但似乎没有
  • HTML 画布从 getImageData 返回“偏离一些”字节

    我找到getImageDataHTML 画布似乎返回不正确的字节值 我使用以下 Python 代码生成了 1x1 px 图像 from PIL import Image import numpy as np a np array 12 18
  • 即使切换它时,hasClass 也始终返回 false

    我有以下代码
  • React Redux Toolkit:如何使用 createSlice 将初始状态存储到 localStorage?

    我对如何将我的任务切片的初始状态存储到我的本地存储中有点太困惑了 你能帮我解决这个问题吗 我想要的结果是 如果应用程序运行 initialState 将存储在 localStorage 中 因为我正在做的是在我的组件中使用 useSelec
  • 如何拦截javascript中innerHTML的变化?

    我需要拦截网页内单元格内容的任何更改 以下代码显示 addEventListener 不起作用 function modifyText alert var el document getElementById mycell el inner
  • 如何从索引文件迭代多个导入的模块

    我有一个名为Polygons我在那里创建了一个index jsfile 以导出目录中的所有文件 它看起来像这样 export default as europe from europe export default as northAmer
  • ASP.NET MVC3 Ajax.ActionLink - 条件确认对话框

    我有一个 Ajax ActionLink 仅当满足某些条件 用户有未保存的更改 时 我才希望显示一个确认对话框 我创建了一个 JavaScript 函数 它根据需要显示确认对话框 并根据响应返回 true 或 false 我将其绑定到 Ac
  • 如何在功能性 React 组件中使用错误边界?

    I can 将类设置为错误边界 https reactjs org blog 2017 07 26 error handling in react 16 html在 React 中通过实现componentDidCatch 是否有一种干净的

随机推荐

  • 如何调整 UITableView 的 tableHeaderView 的大小?

    我在调整 tableHeaderView 大小时遇到 问题 这么简单是行不通的 1 创建一个UITableView和UIView 100 x 320像素 2 将UIView设置为UITableView的tableHeaderView 3 构
  • 使应用程序成为系统关键流程

    我怎样才能创建一个关键系统进程 以便它不能从 C 中的任务管理器结束 一般来说 这是不可能的 因为这会剥夺用户的控制权 Windows 甚至允许您终止高度关键的进程 例如 csrss exe 请不要尝试终止它 保证立即出现 BSOD Ray
  • Kubernetes Pod 事件显示为“

    我们正在调查与 Azure Kubernetes 服务上的 Pod 启动缓慢相关的问题 Pod 启动完成后 我们将无法看到历史事件 最新的事件日志显示为
  • Angular Material 自定义组件主题

    我正在尝试在自定义 Angular Material 主题中为其他一些组件使用自定义调色板中的颜色 例如 带有垫子工具栏的 div 和带边距的图标 应使用主要背景颜色填充 关于主题的 Angular Material 指南说道 主题文件不应
  • Java Connection.close 是否回滚?

    Java Connection close 是否回滚到finally 块 我知道 Net SqlConnection close 可以做到这一点 有了这个 我可以在没有 catch 的情况下创建 try finally 块 Example
  • 如何配置仅在生产模式下运行 http 的 Keycloak 18?

    我遇到的情况是 我在终止安全 https 连接的反向代理后面运行 Keycloak 18 0 0 因此 我想构建一个 Docker 镜像 将 Keycloak 配置为仅侦听 http 例如端口 8080 我已经调整了Dockerfile来自
  • Nuxt 致命错误 TypeError:无法解构“this”的属性“nuxt”,因为它未定义

    当我尝试构建 docker 映像时 运行后出现此错误yarn build 0 0 496 yarn run v1 22 19 0 0 531 nuxt build 0 1 538 Using Tailwind CSS from assets
  • 如何使用 azure pipeline 生成 .AAB 文件并签署 Android 应用程序包

    我想使用 Azure 管道生成 Android 应用程序包 aab 文件 但在生成 Android 应用程序包文件时遇到问题 我已使用以下 Gradle 任务来生成并签署 aab 文件 但是 它生成 APK 文件 我想生成 aab 文件 t
  • Xcode 8.1 beta 3 - AQDefaultDevice 消息 [重复]

    这个问题在这里已经有答案了 从 beta2 开始 在创建音频输出单元后 我每两秒就会收到一条消息 2016 10 14 11 31 21 572479 MyProduct 94063 8294923 aqme 254 AQDefaultDe
  • 当条码扫描仪读取条码时,EditText焦点消失

    我需要读取应用程序的条形码 我为此使用触发式条码扫描仪 通过 USB 进行通信 如您所知 条形码扫描仪的工作原理类似于键盘 当设备读取条形码时 它会尝试将值写入具有焦点的输入 用户按下扳机 条码扫描器开始工作 直到 条码读取成功 然后它进入
  • 如何有选择地观察 Android Room 数据库 INSERT、DELETE 和 UPDATE 事件?

    我的 DAO 是这样设计的 Dao interface FooDao Query SELECT FROM foo LiveData
  • 按字母/字典顺序排列的两个字符串的平均值

    假设您采用字符串 a 和 z 并按字母顺序列出它们之间的所有字符串 a b c x y z 取这个列表的中点 你就会找到 m 所以这有点像取这两个字符串的平均值 您可以将其扩展到具有多个字符的字符串 例如 aa 和 zz 之间的中点将位于列
  • Wix\heat.exe 奇怪的输出

    我有一个目录 其中有一个文件 Iesi Collections dll 当我运行以下命令时 heat exe dir D MyDir cg References srd o D Product wxs nologo gg g1 dr INS
  • Perl 守护进程不与 Sleep() 一起工作

    我使用编写了一个简单的测试守护进程过程 守护进程 http search cpan org deti Proc Daemon 0 14 lib Proc Daemon pod 这是守护进程 usr bin perl use Proc Dae
  • Mac OSX 中菜单栏图标的双击操作

    我正在编写一个显示菜单栏图标的小型 Mac OSX 应用程序 单击后 会弹出一个菜单 我希望菜单栏图标有一个 默认 操作 基本上 双击时执行某个操作 而无需从菜单中选择该操作 我查了一下苹果文档 里面有这样的东西NSStatusItem c
  • 由于缺少定义,在 .net Core 应用程序上构建失败

    我正在尝试使用 CLI 构建我的 NET Core 应用程序dotnet build 但每次我都会收到此错误 IConfigurationBuilder 不包含 AddEnvironmentVariables 的定义 并且找不到接受 ICo
  • Java中的全局变量

    Java 中如何定义全局变量 要定义全局变量 您可以使用 static 关键字 public class Example public static int a public static int b 现在您可以从任何地方访问 a 和 b
  • django-oauth-toolkit :自定义身份验证响应

    我是 Django OAuth 工具包的新手 我想自定义身份验证响应 我在 django 应用程序上的身份验证 url 配置是 url authenticate include oauth2 provider urls namespace
  • 使用自定义视图状态提供程序会出现哪些陷阱?

    我最近开始研究如何使用自定义视图状态提供程序将视图状态的存储从页面移动到服务器 这样做的明显优点是减少渲染的页面大小 从而提高用户体验 另外 据我所知 最大的缺点是服务器内存使用量会增加 对于这个问题 我可以轻松地将存储移动到与 Web 服
  • TypeScript 是否可以从动态对象推断键?

    我在这里想要实现的是从数组生成的对象的智能感知 自动完成 类似于 Redux 的 Action Creator 一个字符串数组 string 可以简化为具有形状的对象 string string 例如 const a ONE TWO THR