排除枚举但仍在TypeScript中返回枚举

排除枚举但仍在TypeScript中返回枚举,typescript,Typescript,为了在typescript枚举中使用项的子集,我们执行如下操作: enum运算符{ 相等='相等', 不相等='不相等', LESS=‘LESS’, 更大=‘更大’, } 类型EqualOperators=Exclude 有没有办法让EqualOperators成为枚举而不是类型,这样我就可以在脚本中使用它 为了澄清,当我说“在脚本中使用它”时,我的意思是能够在javascript函数中使用enum值,这是类型无法实现的,例如: enum运算符{ 相等='相等', 不相等='不相等', LES

为了在typescript枚举中使用项的子集,我们执行如下操作:

enum运算符{
相等='相等',
不相等='不相等',
LESS=‘LESS’,
更大=‘更大’,
}
类型EqualOperators=Exclude
有没有办法让
EqualOperators
成为
枚举
而不是
类型
,这样我就可以在脚本中使用它

为了澄清,当我说“在脚本中使用它”时,我的意思是能够在javascript函数中使用
enum
值,这是
类型
无法实现的,例如:

enum运算符{
相等='相等',
不相等='不相等',
LESS=‘LESS’,
更大=‘更大’,
}
函数getOperator(){
if(运算符相等){
返回“=”;
}
if(运算符不等于){
返回“!=”;
}
抛出新错误(“无效运算符”);
}

谢谢

您可以通过执行以下操作来完成此操作:

enum运算符{
相等='相等',
不相等='不相等',
LESS=‘LESS’,
更大=‘更大’,
}
常量EqualOperators=运算符作为省略;
EqualOperators类型=EqualOperators类型[EqualOperators类型键];

枚举既可以用作类型,也可以用作常量值,如下所示:

enum Operator {
  EQUAL = 'EQUAL',
  NOT_EQUAL = 'NOT_EQUAL',
  LESS = 'LESS',
  GREATER = 'GREATER',
}

function getOperator(op: Operator) {
  if (op == Operator.EQUAL) {
    return "=";
  }
  if (op == Operator.NOT_EQUAL) {
    return "!=";
  }
  if (op == Operator.LESS) {
    return "<";
  }
  if (op == Operator.GREATER) {
    return ">";
  }

  throw new Error('invalid operator');
}

console.log(getOperator(Operator.EQUAL));
console.log(getOperator(Operator.NOT_EQUAL));
console.log(getOperator(Operator.LESS));
console.log(getOperator(Operator.GREATER));
console.log(getOperator('wrong')); // error
console.log(getOperator('wrong' as any)); // works but will throw an error when running
enum运算符{
相等='相等',
不相等='不相等',
LESS=‘LESS’,
更大=‘更大’,
}
函数getOperator(op:Operator){
if(op==运算符.EQUAL){
返回“=”;
}
if(op==运算符。不等于){
返回“!=”;
}
if(op==运算符小于){
返回“”;
}
抛出新错误(“无效运算符”);
}
log(getOperator(Operator.EQUAL));
console.log(getOperator(Operator.NOT_EQUAL));
console.log(getOperator(Operator.LESS));
console.log(getOperator(Operator.GREATER));
console.log(getOperator('error'));//错误
console.log(getOperator('error'as any));//可以工作,但在运行时会抛出错误

如前所述,typescript枚举同时作为类型和对象运行。需要明确的是,所有类型和接口在运行时都会消失,但对象仍然存在。因此,换句话说,要有一个类似于
if(op===Operator.EQUAL)
的条件,
操作符必须在运行时存在(它确实存在,因为我们在这里使用的是枚举的“object half”)

在您的示例中,
运算符
“对象”的行为类似于此对象:

{
  EQUAL: 'EQUAL',         // Operator.EQUAL
  NOT_EQUAL: 'NOT_EQUAL', // Operator.NOT_EQUAL
  LESS: 'LESS',           // Operator.LESS
  GREATER: 'GREATER',     // Operator.GREATER
}
现在,当您使用TypeScript的类型系统从enum派生一个新类型时,您所做的只是创建一个类型,但是要使用if作为对象(如
if
条件中),您还需要实例化一个对象。我提出了以下方法,其好处是利用类型系统来确保在创建常量对象时不会遗漏任何内容(并且还确保仅为每个“键”分配适当的值)

优点是您可以清楚地说明“相等”运算符是什么,如果您添加了新的运算符,您只需要记住在它们是相等运算符时更新
EqualOperators
类型,我觉得这是一个更自然的思考过程,而不是记住更新
EqualOperators
类型,因为它们不是相等运算符。但这两种方法都不理想,因为您不必记住更新另一个定义。因此,要点是,当原始枚举的定义为以下各项之一时,使用我在这里建议的类型定义效果最佳:

  • 不会有太大的变化(或者可能重命名元素)
  • 将仅通过向“in”组添加元素(此处的相等运算符)进行更改
  • 将仅通过向“out”组添加元素(不相等,例如,更少、更大)进行更改

  • “在脚本中使用它”具体如何?用例将推动实现。根据这里的代码,我可能会提出建议,但如果没有用例,我不能确定。@jcalz请查看更新的说明,谢谢!这个例子是。。。怪异
    if(Operator.EQUAL)
    将始终返回
    true
    。你能把这里的代码变成一个真正演示你想要完成什么的代码吗?大概你想在某个地方写
    EqualOperators.EQUAL
    ;你能举例说明这一点吗?最好是一些能够证明某个人可能在某处拥有的用例的东西?如果您检查可能的解决方案,看看它是否满足您的需求,这也会很有帮助。我所做的就是使用原始enum对象作为新的enum对象,因为它是一个超集。如果这不起作用,那么我希望有一个代码示例来说明它是如何起作用的。祝你好运@吉米:为什么你把jcalz的答案贴出来,然后又把它删除了?看起来这就是答案。不
    type EqualOperators = Omit<typeof Operator, 'LESS' | 'GREATER'>;
    
    const EqualOperators: EqualOperators = {
      EQUAL: Operator.EQUAL,
      NOT_EQUAL: Operator.NOT_EQUAL,
    }
    
    type EqualOperators = Pick<typeof Operator, 'EQUAL' | 'NOT_EQUAL'>;