typescript - 如何从另一个枚举声明子集枚举
问题描述
然后是代码:
enum all {
a = 'a',
b = 'b',
c = 'c',
}
// what I want enum
enum wanted {
c = 'c',
}
我知道有一些解决方案,例如
type wanted = Exclude<all, all.a | all.b> // type wanted = all.c
但是类型与枚举不同,因为它不可迭代!
解决方案
枚举只是运行时的对象。例如,您的枚举all
被转换为:
var all;
(function (all) {
all["a"] = "a";
all["b"] = "b";
all["c"] = "c";
})(all || (all = {}));
// Essentially equivalent to
const all = {a: 'a', b: 'b', c: 'c'}
因此,您可以all
像使用任何普通的 JavaScript 对象一样使用。有许多不同的方法可以选择/省略某些属性:
// ES2015 Destructuring
const {a, b, ...wanted} = all
// ES2019 Object.fromEntries
const wanted = Object.fromEntries(
Object.entries(all)
.filter(([key]) =>
key === 'c'
// or if you wanted to exclude instead
// !['a', 'b'].includes(key)
)
) as {c: 'c'}
如果你想让最后一个例子更安全,你可以使用这个助手:
const pick = <T extends Record<string, unknown>, K extends keyof T>(
obj: T,
keys: readonly K[]
): Pick<T, K> =>
Object.fromEntries(
Object.entries(obj).filter(([key]) =>
(keys as readonly string[]).includes(key)
)
) as Pick<T, K>
const wanted = pick(all, ['c'])
或者也许这是为了省略属性:
const omit = <T extends Record<string, unknown>, K extends keyof T>(
obj: T,
keys: readonly K[]
): Omit<T, K> =>
Object.fromEntries(
Object.entries(obj).filter(
([key]) => !(keys as readonly string[]).includes(key)
)
) as Omit<T, K>
const wanted = omit(all, ['a', 'b'])
在 TypeScript 中,类型可以与值具有相同的名称,因此如果您wanted
也想成为一个类型(就像您写出枚举一样),您可以wanted
使用Exclude
or定义一个类型Pick
(就像在您的示例中一样)。
推荐阅读
- powershell - Win10 Powershell - 简单的 If/Elseif 取决于条件顺序?
- javascript - 如何在 Vue.js 项目中添加字体
- angular - Angular HTTP Get 调用陷入无限循环
- tcp - 如何让 nmap 优雅地关闭连接?
- python - 使用 argparse 显示主题
- amazon-web-services - Amazon S3、Cloudfront、HTTPS 有时无法加载
- angular - 如何使默认选择的 API 检索到的元素
- docker - 使用另一个端口运行 jboss docker 命令
- python - 如何在Python中实现类实例与浮点数和类实例之间的乘法
- r - 错误 read_xlsx (v1.0):read_fun 中的错误(路径 = 路径,工作表 = 工作表,限制 = 限制,垫片 = 垫片,:std::bad_alloc