然后就是代码:
enum all {
a = 'a',
b = 'b',
c = 'c',
}
// what I want enum
enum wanted {
c = 'c',
}
Run Code Online (Sandbox Code Playgroud)
我知道有一些解决方案,比如
type wanted = Exclude<all, all.a | all.b> // type wanted = all.c
Run Code Online (Sandbox Code Playgroud)
但类型与枚举不同,因为它是不可迭代的!
枚举只是运行时的一个对象。例如,您的枚举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'}
Run Code Online (Sandbox Code Playgroud)
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'}
Run Code Online (Sandbox Code Playgroud)
如果你想让最后一个例子更加类型安全,你可以使用这个助手:
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'])
Run Code Online (Sandbox Code Playgroud)
或者也许这是为了省略属性:
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'])
Run Code Online (Sandbox Code Playgroud)
在 TypeScript 中,类型可以与值具有相同的名称,因此如果您wanted也想成为一种类型(就像您写出了枚举一样),您可以使用 或 定义类型wanted(Exclude就像Pick在您的示例中一样)。
| 归档时间: |
|
| 查看次数: |
2844 次 |
| 最近记录: |