【发布时间】:2021-08-01 02:02:33
【问题描述】:
我们正在尝试构建一个具有属性variant 的组件,该属性只能设置为"primary" 或"secondary"(枚举)。目前,我们只是将属性声明为一个字符串,但我们想知道是否有更好的方法来处理枚举?例如,我们是否应该以某种方式验证当前值是枚举的一部分?如果不是,我们应该抛出错误吗?
【问题讨论】:
标签: lit-element lit
我们正在尝试构建一个具有属性variant 的组件,该属性只能设置为"primary" 或"secondary"(枚举)。目前,我们只是将属性声明为一个字符串,但我们想知道是否有更好的方法来处理枚举?例如,我们是否应该以某种方式验证当前值是枚举的一部分?如果不是,我们应该抛出错误吗?
【问题讨论】:
标签: lit-element lit
我在Slack 上提出了这个问题,我得到的答案倾向于将属性声明为字符串,并在属性值无效时使用hasChanged() 在控制台中显示警告。
标准 HTML 元素接受任何字符串作为属性值并且不会抛出异常,因此 Web 组件的行为方式可能应该相同。
这对我来说听起来很合理。
【讨论】:
如果您使用的是 TypeScript,我建议您只使用字符串。您可以使用export type MyEnum = 'primary' | 'secondary' 声明它,然后使用@property() fooBar: MyEnum 进行构建时间检查。您也可以使用 @ts-check 在普通 JS 中使用 @type MyEnum 执行此操作。
如果枚举用于组件选项或映射到将再次验证的服务器端枚举,则此方法效果很好。
但是,如果您想验证用户对枚举的输入或大量循环它们,这不太好。当 JS 运行时,它没有类型的可见性。您需要一个对象字典,例如:
const MyEnum = Object.freeze({
primary: 'primary',
secondary: 'secondary'
});
// Enforce type in TS
const value: keyof MyEnum;
// Validate
const validated = MyEnum[input.toLower()];
// Loop
for(const enumVal of Object.keys(MyEnum)) ...
// Or Convert to a different value type
const MyEnum = Object.freeze({
primary: 1,
secondary: 2
});
这些有点特殊。同样,如果您使用的是 TypeScript,它有一个 enum 关键字可以编译成这样的东西,我会使用它而不是自己滚动。除非您需要验证、循环或转换值,否则字符串是更好的选择。
【讨论】: