Ended up going with `superstruct`. It's neat, a bit less verbose than io-ts and has better type inference in some places.
Native enums support is not there yet but can be worked around https://github.com/ianstormtaylor/superstruct/issues/993
Had a bit of a headache trying to make it so 1Password doesn't think the text input was a password/username field. Turns out naming it with a name like `*search` fixes it 😩
The social network of the future: No ads, no corporate surveillance, ethical design, and decentralization! Own your data with Mastodon!