从元组/数组值派生联合类型

2024-06-25

假设我有一个数组:

const list = ['a', 'b', 'c']

是否可以从这个值联合类型派生出'a' | 'b' | 'c'?

我想要这个是因为我想定义只允许来自静态数组的值的类型,并且还需要在运行时枚举这些值,所以我使用 array.

如何使用索引对象实现它的示例:

const indexed = {a: null, b: null, c: null}
const list = Object.keys(index)
type NeededUnionType = keyof typeof indexed

是否可以在不使用索引地图的情况下做到这一点?


当前答案

在 TypeScript 3.4 及更高版本中,您可以使用const断言 https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions告诉编译器保留特定的文字类型 https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types of any 文字值 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#literals在一个表达式中。

const list = ['a', 'b', 'c'] as const; // const assertion
type NeededUnionType = typeof list[number]; // 'a'|'b'|'c';

Playground 代码链接 https://www.typescriptlang.org/play?#code/MYewdgzgLgBANgS2jAvDA2gcgIaYDQyYBG+hwmAujNhDKJFANwwD0LMAKgMoDMAdABYYEAJ5go2AB4AoKCIAOAUxgA5RYoAmmgKpgE4DguVo5SkADN4SKOjABXALZFFAJwrM2hXAB9imX+SMQA

2019 年 2 月更新

In TypeScript 3.4,预计于 2019 年 3 月发布 https://github.com/Microsoft/TypeScript/wiki/Roadmap#34-march-2019可以告诉编译器推断文字元组的类型作为文字元组,而不是说,string[],通过使用as const syntax https://github.com/Microsoft/TypeScript/pull/29510。这种类型的断言使编译器推断出值可能的最窄类型,包括使所有内容readonly。它应该看起来像这样:

const list = ['a', 'b', 'c'] as const; // TS3.4 syntax
type NeededUnionType = typeof list[number]; // 'a'|'b'|'c';

这将消除对任何类型的辅助函数的需要。再次祝大家好运!


2018 年 7 月更新

看起来,从 TypeScript 3.0 开始,TypeScript 将有可能自动推断元组类型 https://github.com/Microsoft/TypeScript/pull/24897。一旦被释放,tuple()您需要的功能可以简洁地写为:

export type Lit = string | number | boolean | undefined | null | void | {};
export const tuple = <T extends Lit[]>(...args: T) => args;

然后你可以像这样使用它:

const list = tuple('a','b','c');  // type is ['a','b','c']
type NeededUnionType = typeof list[number]; // 'a'|'b'|'c'

希望这对人们有用!


2017 年 12 月更新

自从我发布这个答案以来,如果您愿意向库添加函数,我找到了一种推断元组类型的方法。查看功能tuple() in tuple.ts https://gist.github.com/jcalz/381562d282ebaa9b41217d1b31e2c211。使用它,您可以编写以下内容而不必重复自己:

const list = tuple('a','b','c');  // type is ['a','b','c']
type NeededUnionType = typeof list[number]; // 'a'|'b'|'c'

祝你好运!


原版 2017 年 7 月

一个问题是字面意思['a','b','c']将被推断为类型string[],因此类型系统会忘记具体的值。您可以强制类型系统将每个值记住为文字字符串:

const list = ['a' as 'a','b' as 'b','c' as 'c']; // infers as ('a'|'b'|'c')[]

或者,也许更好,将列表解释为元组类型:

const list: ['a','b','c'] = ['a','b','c']; // tuple

这是令人讨厌的重复,但至少它不会在运行时引入无关的对象。

现在你可以像这样得到你的工会:

type NeededUnionType = typeof list[number];  // 'a'|'b'|'c'.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从元组/数组值派生联合类型 的相关文章

随机推荐

  • Kotlin如何将文件移动到其他目录?

    假设我有以下文件层次结构 C Users sanpleuser Downloads gt test txt C 用户 样本用户 文档 我想要实现的是将 test txt 文件从下载移动到文档 有人可以帮我解决这个问题吗 Kotlin 为 J
  • Laravel 中无效后防止重定向到主页

    我正在使用 Laravel 5 3 开发 RESTful API 因此我正在使用我的控制器测试一些功能和请求 我需要做的一件事是在数据库中添加字段之前验证用户发送的请求 因此 我使用自定义 FormRequest 来验证它 当我在 Post
  • Jetpack Compose:布局检查器未显示重组计数菜单

    Android Studio 大黄蜂补丁 3 从这个页面 它说我可以看到重组计数 https developer android com jetpack compose tooling recomposition counts https
  • 通过systemd服务启动烧瓶

    有一个systemd服务文件 etc systemd system flask app service Unit Description flask app After network target Service User root Wo
  • VueJS:以冒号为前缀的 html 属性表示什么?

    Example
  • 回调在 Angular2/Firebase 中生成“TypeError:这是未定义的”

    我试图了解这里发生了什么以及为什么如果我以某种方式调用函数时会收到错误 而当我以不同的方式调用函数时却不会收到错误 这是首先产生错误的方式 播放器 service ts 文件 in the Injectable i have private
  • 从 subversion 标签自动构建

    我正在尝试自动化工程组的构建过程 作为自动化的一部分 我试图达到这样的程度 应用遵循某种模式的特定标签的行为将启动一个自动化过程 该过程将执行以下操作 查看源代码 从模板创建构建脚本 构建项目 我非常确定我可以使用 subversion 中
  • 将 Base64 解码的 NSData 转换为 NSString

    我正在尝试对 Base64 数据进行编码和解码 但是在解码 Base64 数据时 它返回一堆十六进制值 但我无法使用 NSlog 显示或打印原始可读字符串 下面的代码无法打印任何内容 只是空的 有人可以帮忙吗 谢谢 gt gt NSStri
  • 如何指定 JBoss AS7 中的 Web 应用程序使用哪个安全域?

    我正在使用 JBoss AS7 JSF 2 1 我正在尝试使用数据库登录模块对我的 Web 应用程序中特定资源的用户进行身份验证 在standalone xml中有3个安全域 other jboss web policy 和 jboss e
  • OOP:什么时候它是一个对象?

    我正在尝试理解面向对象 我当然明白一点 但有时我并不是百分百清楚 你如何决定什么应该变成一个对象 另一个大的整个对象的小对象部分 或者什么不值得成为一个对象 或者也许它应该只是那个大的整个对象的属性 对于一扇门来说 我猜门把手应该是一个独立
  • “==”对象相等的标准定义是什么?

    There seems与普遍理解之间的不匹配 以及它的实际作用 给出这个问题的一些背景 typeof new Number 1 returns object typeof new String 1 returns object typeof
  • 如何非递归地捕获 ImportError?

    假设我们要导入一个名为user py 这可能会失败 try import user except ImportError logging info No user script loaded 我们怎样才能确保只捕获可能的导入失败user p
  • JavaScript 无法在 HTML 文件中运行

    我已阅读有关此主题的可用链接 但它们没有帮助 我正在尝试运行以下代码 menu html 在另一个页面的 div 中加载 world html 并且显示 HTML 但不显示 JavaScript 起初 我将 JS 放在一个单独的文件中 但当
  • std::function<> 和标准函数指针之间的区别? [复制]

    这个问题在这里已经有答案了 std function 和标准函数指针有什么区别 that is typedef std function
  • Python Tkinter Tk 支持清单框吗?

    我正在尝试在 GUI 中创建清单框 可以做 Tkinter 吗 我不想要复选框列表 我知道 Python Wx GUI 开发有这种支持 但我正在寻找 Tk 中的支持 如果有人有想法 请分享详细信息或方法的链接 Tkinter 没有像 wxP
  • 回发在 Firefox 中对 asp.net(C#) 页面不起作用

    我的 mozilla 火狐浏览器有问题 我正在使用 ASP NET 语言开发一个网站 并且在表单中有一个按钮 当我单击 onclick 属性上的按钮时 我正在调用一个函数 并且该函数执行回发 此场景适用于 Chrome 和 Internet
  • python 从字符串创建对象

    我有下一个情况 以下方法的目标是返回从传入字符串创建的对象 所以我有 class Situation Generator pass 以及父类中的方法 class Generator object def createsituation se
  • psql 的备用输出格式显示每行一列以及列名

    我在 Ubuntu 上使用 PostgreSQL 8 4 我有一个带有列的表格c1通过cN 这些列足够宽 选择所有列会导致一行查询结果多次换行 因此 输出很难阅读 当查询结果仅包含几行时 如果我可以查看查询结果 使得每行的每一列都位于单独的
  • 更改 sqlite 中列中的值

    我需要更新某个表中的列中的值 我试过这个 public void updateOneColumn String TABLE NAME String Column String rowId String ColumnName String n
  • 从元组/数组值派生联合类型

    假设我有一个数组 const list a b c 是否可以从这个值联合类型派生出 a b c 我想要这个是因为我想定义只允许来自静态数组的值的类型 并且还需要在运行时枚举这些值 所以我使用 array 如何使用索引对象实现它的示例 con