我对TypeScript只有几个月的时间,深入研究其内部工作原理。也许有人可以帮助我提高理解力。
在我们的angular2应用程序中,我们将enum
特权定义为:
export enum UserPrivileges{
SUPER,
USER,
GUEST
}
我们在函数定义中将此类型包含为枚举类型的数组:
checkPrivileges(userPrivileges: UserPrivileges[]) {...}
我们用于为用户查找权限的模式是:
this.isSuperUser = userPrivileges.includes(UserPrivileges[UserPrivileges.SUPER]);
问题
TypeScript抱怨由于Array.prorotype.includes()
方法调用(与.indexOf()
相同的问题),“类型'字符串'的参数不能分配给'UserPrivileges'类型。)
我认为这种形式的就地铸造都不起作用:
this.isSuperUser = userPrivileges.includes(<string>UserPrivileges[UserPrivileges.SUPER]);
this.isSuperUser = userPrivileges.includes(UserPrivileges[UserPrivileges.<string>SUPER]);
我们可以“欺骗”tsc linter并将函数签名更改为:
checkPrivileges(userPrivileges: string[]) {...}
...但是那么使用类型有什么意义呢?
这必须是一个常见的用例,但我必须缺少必要的装饰器?是否需要添加到枚举类型定义中以允许将其解释为字符串?
修改
要清楚,我们的后端返回数组中特权的字符串标记,例如userPrivileges = ["SUPER", "GUEST", "USER"]
。 UserPrivileges
enum类型旨在模仿这一点。
旧的方式,有效(期待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返回进行比较?
答案 0 :(得分:5)
而不是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<T extends Enum>
这是Array<string>
。
此时您有几个选择。您可以决定使用字符串并将UserPrivileges创建为
const UserPrivileges = {
['SUPER'] = 'SUPER',
['USER'] = 'USER',
['GUEST'] = 'GUEST',
}
或者您可以将字符串列表转换为真实的枚举列表。然后,从该列表开始工作应该按预期运行。