如何在Array [T]中找到元素<t>,其中<t>是一个枚举?

时间:2017-01-16 17:07:46

标签: angular typescript ecmascript-6

我对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返回进行比较?

1 个答案:

答案 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',
}

或者您可以将字符串列表转换为真实的枚举列表。然后,从该列表开始工作应该按预期运行。