我只有几个月的时间来研究TypeScript,深入研究其内部工作原理.也许有人可以帮助提高我的理解力.
在我们的angular2应用程序中,我们有一个enum
权限定义为:
export enum UserPrivileges{ SUPER, USER, GUEST }
我们在函数定义中包含此类型作为枚举类型的数组:
checkPrivileges(userPrivileges: UserPrivileges[]) {...}
我们用于为用户查找权限的模式是:
this.isSuperUser = userPrivileges.includes(UserPrivileges[UserPrivileges.SUPER]);
问题
TypeScript抱怨"类型'字符串'的参数不能分配给类型'UserPrivileges'",因为Array.prorotype.includes()
方法调用(与.indexOf()
.相同的问题.)
我认为这种形式的就地铸造都不起作用:
this.isSuperUser = userPrivileges.includes(UserPrivileges[UserPrivileges.SUPER]); this.isSuperUser = userPrivileges.includes(UserPrivileges[UserPrivileges. SUPER]);
我们可以"欺骗"tsc linter并将函数签名更改为:
checkPrivileges(userPrivileges: string[]) {...}
...但是那么使用类型有什么意义呢?
这必须是一个常见的用例,但我必须缺少必要的装饰器?是否需要添加到枚举类型定义中以允许将其解释为字符串?
编辑
为了清楚起见,我们的后端返回数组中特权的字符串标记,这样userPrivileges = ["SUPER", "GUEST", "USER"]
.该UserPrivileges
枚举类型是意在模仿这一点.
旧的方式,工作(期待true
):
userPrivileges.indexOf(UserPrivileges[UserPrivileges.SUPER]) > -1;
因为
UserPrivileges.SUPER
评估为0
(由于发出的JS Paarth解释)
UserPrivileges[0]
然后计算到字符串 "SUPER"
...这是userPrivileges[]
来自后端的值.
然而,这些将不合需要地(但可预测地)返回 false
userPrivileges.includes(UserPrivileges.SUPER); userPrivileges.indexOf(UserPrivileges.SUPER) > -1;
出于与上述相同的原因:userPrivileges[]
从服务器返回的不包含值0
.
"当你将一个枚举值反馈给自己时,你将会找回该字符串." 对于提出的解决方案,似乎我必须使用类型的数字索引 UserPrivileges[0]
来获取字符串以与REST返回进行比较?
而不是UserPrivileges[UserPrivileges.SUPER]
使用UserPrivileges.SUPER
this.isSuperUser = userPrivileges.includes(UserPrivileges.SUPER);
typescript中的非const枚举能够前后移动(它们是具有字符串映射到值的对象和字符串的值).它可能在JS中看起来像这样.
const UserPrivileges = { ['SUPER'] = 0, ['USER'] = 1, ['GUEST'] = 2, [0] = 'SUPER', [1] = 'USER', [2] = 'GUEST', }
因此,当您将枚举值反馈回自身时,您将返回字符串 - 这解释了您所看到的错误,因为已UserPrivileges.SUPER
解析0
,并且基于枚举上的数字索引访问属性会返回字符串名称.
更新了编辑中的信息.
为了清楚起见,我们的后端返回数组中特权的字符串标记,这样
userPrivileges = ["SUPER", "GUEST", "USER"]
如果这是真的,那么我怀疑我们可能会互相说话.变量userPrivileges
不是一个.Array
这是一个Array
.
此时您有几个选择.您可以决定使用字符串并创建UserPrivileges
const UserPrivileges = { ['SUPER'] = 'SUPER', ['USER'] = 'USER', ['GUEST'] = 'GUEST', }
或者您可以将字符串列表转换为真实的枚举列表.然后,从该列表开始工作应该按预期运行.