【发布时间】:2021-04-24 00:21:24
【问题描述】:
假设我有这些类型:
type StepA = // ...
type StepB = // ...
type StepC = // ...
type Steps = [StepA, StepB, StepC]
我想要一个实用程序类型SomeUtilityType<T> 以便:
type StepsCombinations = SomeUtilityType<Steps>
// type StepsCombinations =
// | { step: 0; value: StepA }
// | { step: 1; value: StepB }
// | { step: 2; value: StepC };
我应该如何定义SomeUtilityType<T>?
编辑
如果Steps被定义为一个对象
type Steps = {0: StepA, 1: StepB, 2: StepC}
这个使用Distributive Conditional Types 的实用程序可以解决问题(参见playground):
type SomeUtilityType<
V extends { [index: number]: unknown },
T extends keyof V = keyof V
> = T extends unknown
? { step: T; value: V[T]; }
: never;
但我更希望避免使用多余的键 0, 1 , 2... 定义对象。
我想我可以使用上面的 SomeUtilityType 类型定义,如果有某种方法可以获得数组中所有索引的联合,例如 Indexes<Steps> // --> 0 | 1 | 2
【问题讨论】:
-
Steps可能存在多长时间? TypeScript 倾向于提供像"0"这样的元组键字符串表示,而不是0。如果你想要{step: "2", value: StepC},那很好。如果您需要将"2"转换为2,那么我们需要编写一些东西来做到这一点,这并不简单。如果您只需要支持最大有限长度的元组,那么我们可以考虑到这一点来编写实用程序类型,而不是尝试在类型系统中表示“将字符串转换为等效数字”。 -
步数会很短,比如说少于 10 个位置。我同意
"2"而不是2。顺便说一句,我刚刚用我找到的一些替代解决方案编辑了我的问题,但仍然不是最理想的。 -
好的,看我的回答。
标签: typescript