Typescript枚举相等编译时错误

时间:2018-01-09 15:06:35

标签: angular typescript enums

我正在编写用户角色的基本实现,只允许某些用户使用typescript枚举访问网站的某些部分。

我有一个表示用户主要角色的字符串,例如“经理”,我想将其与枚举类型进行比较,以便我可以实现诸如“部门经理或更高的用户可以看到此信息”之类的想法。

这个简单的比较似乎没有记录(LHS应该返回一个数字),除非我遗漏了一些东西:

enum systemRoles {
  Staff,
  DeptMgr,
  Manager,
  GM,
  Executive,
  Owner
}

userTypeIsAuthorized(){
return systemRoles[this.currentUser().type] === 4
}

如上所述编写userTypeIsAuthorized()会产生编译错误:“Operator'==='不能应用于类型'string'和'number'”。如果我改为return systemRoles['Executive'] === 4,基本上硬编码用户类型而不是访问保存的字符串类型,则没有错误。

以上所有内容实际上只是我尝试了枚举类型的行为。我最终想要的是(伪代码):

return systemRoles[this.currentUser().type] >= systemRoles['Executive']; // return true if the user is an Executive or Owner.

...但是这会产生类似的错误:“运算符'==='不能应用于类型'string'和'systemRoles'”

也许你对我对enum类型的早期误解的解决方案对未来的人有用,如果他们在这里记录的话!

编辑:在阅读了澄清的答案之后,我已经到了这里:

return this.currentUser().type === systemRoles[systemRoles.Executive];

这实际上是一个字符串相等比较,但我需要的是枚举类型中的数字比较。换句话说,上面的工作因为“执行”===“执行”,但我需要返回的是(伪代码):“执行”,用户的类型,大于或等于系统角色执行。所以,如果this.currentUser()。type是“Owner”,我需要返回true - 不是因为字符串“Owner”大于字符串“Executive”(因为O按字母顺序排在E之后) - 但是因为{ {1}} Owner的数值(5)高于enum的数值(4)。换句话说:如果enum有一周中的几天,如果“星期三”在星期一之后,我想返回true。

4 个答案:

答案 0 :(得分:0)

您想要使用枚举,因此请正确使用它们:

enum systemRoles {
  Staff,
  DeptMgr,
  Manager,
  GM,
  Executive,
  Owner
}

function userTypeIsAuthorized() {
    return this.currentUser().type === systemRoles.Executive;
}

使用枚举意味着您不必依赖数组索引,但您可以并且始终应该使用给定的别名。 this.currentUser().type应该已经保存了枚举值,因此您只需将其与想要的角色进行比较。

同样在课堂外,函数名称必须以function关键字为前缀。

答案 1 :(得分:0)

如果使用数字索引为enum编入索引,您将获得enum个字段的名称

declare var type: number;
var xx= systemRoles[type]; // xx will be of type string 

所以编译器是对的,你不能比较它们。

您只需将您拥有的值与枚举值进行比较

即可
this.currentUser().type === systemRoles.Executive;

答案 2 :(得分:0)

可以阅读here

  

反向映射除了使用属性名称创建对象之外   对于成员,数字枚举成员也从中获得反向映射   枚举值到枚举名称。例如,在此示例中:

enum Enum {
    A
}
let a = Enum.A;
let nameOfA = Enum[a]; // "A"
     

TypeScript可能会将其编译为类似下面的内容

JavaScript:

var Enum;
(function (Enum) {
    Enum[Enum["A"] = 0] = "A";
})(Enum || (Enum = {}));
var a = Enum.A;
var nameOfA = Enum[a]; // "A"
     

在这个生成的代码中,枚举被编译成一个对象   存储转发(名称 - >值)和反转(值 - >名称)   映射即可。对其他枚举成员的引用始终作为   属性访问,从不内联。

     

请记住,字符串枚举成员没有获得反向映射   根本生成。

所以你的枚举在js

中编译成这样的东西
{
"0":"Staff",
"1":"DeptMgr",
"2":"Manager",
"3":"GM",
"4":"Executive",
"5":"Owner",
"Staff":0,
"DeptMgr":1,
"Manager":2,
"GM":3,
"Executive":4,
"Owner":5
}

所以当你这样做时

return systemRoles[this.currentUser().type] === 4

由于编译枚举的方式 systemRoles[this.currentUser().type]返回一个字符串,因为

typeof(this.currentUser().type) == typeof(systemRoles)
OR
this.currentUser() is number

在哪里

systemRoles['Executive'] is number

修改 -
你实际上要做的是非常好地使用常量枚举。这也是更好的表现。

可以阅读here

  

避免支付额外生成的代码和额外费用   在访问枚举值时间接,可以使用const   枚举。 Const枚举是使用我们的枚举中的const修饰符定义的:

const enum Enum {
    A = 1,
    B = A * 2 
} 
     

Const枚举只能使用常量枚举表达式而不像常规表达式   枚举它们在编译期间被完全删除。 Const enum   成员在使用网站上内联。这是可能的,因为常数   不能有计算成员。

const enum Directions {
    Up,
    Down,
    Left,
    Right }
     

让路线= [Directions.Up,Directions.Down,Directions.Left,   生成的代码中的Directions.Right]将成为

var directions = [0 /* Up */, 1 /* Down */, 2 /* Left */, 3 /* Right
*/];
     


假设this.currentUser()。type是typeof(systemRoles)或typeof(number)。
你将能够做到

this.currentUser().type > systemRoles.Executive

因为最终所有这些都将被编译为数字

答案 3 :(得分:-1)

同意上述[Parv Sharma]的解释。走出枚举编译的方式,您应该编写:     返回this.currentUser()。type === systemRoles [systemRoles.Executive];

systemRoles [systemRoles.Executive]等于“ Executive”(typeof将为您提供字符串),您的情况下的this.currentUser()。type也是如此。

此处示例 http://www.typescriptlang.org/play/index.html#src=enum%20systemRoles%20%7B%0D%0A%20%20Staff%2C%0D%0A%20%20DeptMgr%2C%0D%0A%20%20Manager%2C%0D%0A%20%20GM%2C%0D%0A%20%20Executive%2C%0D%0A%20%20Owner%0D%0A%7D%0D%0A%0D%0Aclass%20User%20%7B%0D%0A%20%20%20%20%22name%22%3A%20string%3B%0D%0A%20%20%20%20%22type%22%3A%20string%3B%0D%0A%7D%0D%0A%0D%0Avar%20user1%20%3D%20new%20User()%3B%0D%0Auser1.name%20%3D%20%22e1%22%3B%0D%0Auser1.type%20%3D%20%22Executive%22%3B%0D%0A%0D%0Avar%20user2%20%3D%20new%20User()%3B%0D%0Auser2.name%20%3D%20%22u1%22%3B%0D%0Auser2.type%20%3D%20%22Staff%22%3B%0D%0A%0D%0Afunction%20userTypeIsAuthorized(%20user%20)%7B%0D%0A%20%20%20%20return%20user.type%20%3D%3D%3D%20systemRoles%5BsystemRoles.Executive%5D%3B%0D%0A%7D%0D%0Aconsole.log(systemRoles%5B%22Executive%22%5D)%3B%0D%0Aconsole.log(systemRoles%5Buser1.type%5D)%3B%0D%0Aconsole.log(systemRoles%5BsystemRoles.Executive%5D)%3B%0D%0Aconsole.log(systemRoles.Executive)%3B%0D%0A%0D%0Aconsole.log(%20user1.type%20)%3B%0D%0A%0D%0Aconsole.log(typeof%20systemRoles%5BsystemRoles.Executive%5D)%3B%0D%0Aconsole.log(typeof%20user1.type)%3B%0D%0A%0D%0Aconsole.log(userTypeIsAuthorized(user1))%3B%0D%0Aconsole.log(userTypeIsAuthorized(%20user2%20))%3B%0D%0A