We are trying to build a component with a property variant
that should only be set to "primary"
or "secondary"
(enum). Currently, we are just declaring the attribute as a String, but we were wondering if there is a better way for handling enums? For example, should we validate somehow that the current value is part of the enum? Should we throw an error if not?

- 31
- 2
2 Answers
I asked this question on Slack and the answers I got lean towards declaring the property as String and use hasChanged()
to display a warning in the console if the property value is invalid.
Standard HTML elements accept any string as attribute values and don't throw exceptions, so web components should probably behave the same way.
This all sounds reasonable to me.

- 31
- 2
If you're using TypeScript I'd recommend just using strings. You can use export type MyEnum = 'primary' | 'secondary'
to declare it and then use @property() fooBar: MyEnum
to get build time checking. You can use @ts-check
to do this in plain JS with @type MyEnum
too.
This works well if the enums are for component options or that map to server-side enums that will get validated again.
However, if you want to validate user input into enums or loop through them a lot this is less good. As the JS runs it has no visibility of the type. You need an object dictionary, something like:
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
});
These are somewhat idiosyncratic. Again, if you're using TypeScript it has an enum
keyword that compiles to something like this and I'd use that rather than rolling your own. Strings are the better option unless you need to validate, loop or convert the values.

- 150,284
- 78
- 298
- 434