typescript - TypeScript:泛型检查枚举类型
问题描述
有一个过程枚举。它们有不同的步骤,也表示为枚举,如下所示。
enum Process {
Simple = "simple",
Advanced = "advanced"
}
enum SimpleStep {
A = "A",
B = "B"
}
enum AdvancedStep {
A = "A",
B = "B",
C = "C"
}
通过以下语句,我创建了一系列步骤。
const SIMPLE_STEPS = Object.keys(SimpleStep).map(
(k: string) => SimpleStep[k]
);
const ADVANCED_STEPS = Object.keys(AdvancedStep).map(
k => AdvancedStep[k]
);
const ALL_STEPS = {
[Process.Simple]: SIMPLE_STEPS,
[Process.Advanced]: ADVANCED_STEPS
};
我编写了以下函数来获取步骤号。
// ???: Check if S is a step of Process
const getStepNumber = <P extends Process, S>(process: P, step: S) => {
return ALL_STEPS[process].indexOf(step) + 1;
};
// returns 2, which is correct
console.log('step number of B', getStepNumber(Process.Advanced, AdvancedStep.B));
// returns 0. Is it possible to prevent at compile-time?
console.log('step number of C', getStepNumber(Process.Simple, AdvancedStep.C));
正如您在代码示例中看到的那样,是否可以在编译时使用泛型防止以错误的步骤调用函数?
这是游乐场,如果您想尝试整个示例:TS Playground
解决方案
一种选择是引入一个条件类型,它允许您根据提供给函数的值推断所需的步骤枚举(即SimpleStep
或)。这可以按如下方式完成:AdvancedStep
Process
type StepFromProcess<P extends Process> =
P extends Process.Simple ? SimpleStep : AdvancedStep
然后您可以更改您的函数以使用该类型:
const getStepNumber = <P extends Process>(process: P, step: StepFromProcess<P>) => ...
编译器现在将阻止您进行此(无效)调用:
console.log('step number of C', getStepNumber(Process.Simple, AdvancedStep.C));
推荐阅读
- php - mysqldump 仅在生产中将文件保存为 20B,我的本地主机是好的,都使用 MySQL8
- r - 在 R 中计算相关系数时的问题
- replace - Tcl如何替换输入中的数据
- visual-studio-code - 如何在VSCode扩展制作中安装扩展时执行一段代码?
- ssh - 需要使用ansible通过跳转主机使用跳转主机中的key连接到主机
- python - Groupby 一列,然后比较其他两列并在不同列中返回一个值
- javascript - 如何修复 CSS2 变换上的画布模糊:比例(2)?
- opencv - 为什么我不能使用 FFMPEG 作为 OpenCV 的后端?
- youtube - 尝试按标题搜索所有观看次数最多的 youtube 视频,但缺少搜索结果
- python - 将 AMPL 模型转换为 ORTools