Typescript:根据枚举成员的数量获取一个固定长度的元组
Posted
技术标签:
【中文标题】Typescript:根据枚举成员的数量获取一个固定长度的元组【英文标题】:Typescript: Get a tuple with the fixed length according to the number of enum members 【发布时间】:2020-09-19 08:32:21 【问题描述】:假设我有一个枚举
enum Chest
ID,
NAME,
CAPACITY,
OPEN_WIN_POINTS,
我想创建一个长度与枚举中值的数量相同的元组。所以对于上面的例子,我想要长度为 4 的字符串元组:
type ChestStringTuple = EnumTuple<string, Chest>
const correctTuple: ChestStringTuple = ['foo', 'bar', 'baz', 'goo']
const incorrectTuple1: ChestStringTuple = ['foo', 'bar', 'baz'] // The number of tuple members differs from 4
const incorrectTuple2: ChestStringTuple = ['foo', 'bar', 'baz', false] // The tuple has non-string members
有没有办法获取枚举成员的数量并将其用作元组长度?
【问题讨论】:
相关***.com/questions/52489261/… @AlekseyL。这是一个很好的,谢谢!如果我只能以某种方式获得枚举长度。 不要认为这是可能的。尝试描述什么是真正的用例,也许有人可以提供帮助 【参考方案1】:结合 SO 上提出的各种问题的解决方案,我设法创建了一个应该正是您正在寻找的解决方案!
首先,let's grab a type that can build us a tuple!
type BuildTuple<Current extends [...T[]], T, Count extends number> =
Current["length"] extends Count
? Current
: BuildTuple<[T, ...Current], T, Count>
type Tuple<T, Count extends number> = BuildTuple<[], T, Count>
Then we'll hop on over to this SO question, which has some really useful union helper functions!
type UnionToIntersection<U> =(U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never
type UnionToOvlds<U> = UnionToIntersection<U extends any ? (f: U) => void : never>;
type PopUnion<U> = UnionToOvlds<U> extends ((a: infer A) => void) ? A : never;
然后我们将重写该 SO 答案的主要方法,因为我们的目标不是将联合转换为元组(我不建议这样做 - read this for an explanation as to why)
type UnionCount<U, L extends any[] = []> =
0: PopUnion<U> extends infer SELF ? UnionCount<Exclude<U, SELF>, [any, ...L]> : never;
1: L['length'];
[[U] extends [never] ? 1 : 0];
从那里开始,剩下的就相当简单了。我们将制作几个别名类型,以便于阅读
type InterfaceLength<T> = UnionCount<keyof T>;
type EnumLength<T> = UnionCount<T>;
如果我们将所有这些组合在一起,我们就可以创建我们的final枚举
type InterfaceTuple<T, L> = Tuple<T, InterfaceLength<L>>;
type EnumTuple<T, L> = Tuple<T, EnumLength<L>>;
您的代码:
enum Chest
ID,
NAME,
CAPACITY,
OPEN_WIN_POINTS,
type ChestStringTuple = EnumTuple<string, Chest>
const correctTuple: ChestStringTuple = ['foo', 'bar', 'baz', 'goo'] // Valid
const incorrectTuple1: ChestStringTuple = ['foo', 'bar', 'baz'] // Not valid
const incorrectTuple2: ChestStringTuple = ['foo', 'bar', 'baz', false] // Not valid
Playground
使用风险自负。
【讨论】:
我想知道是否有更简洁的方法来获取联合中的元素数量。 . .以上是关于Typescript:根据枚举成员的数量获取一个固定长度的元组的主要内容,如果未能解决你的问题,请参考以下文章