After a few years of trying to make them work, I've given up on TS enums, for the reasons you describe. The union-of-values approach works better, is safer at runtime, and my IDE is smart enough that I can tab-complete to the seemingly 'magic' strings.
Also, 'as const' works magic:
const Suits = ["Hearts", "Diamonds","Clubs","Spades"] as const.
type SuitType = typeof Suits[number]; // Super hacky-looking but works great if you need to change Suits.
This couples especially well with the 'options object' pattern:
const SuitsOptions: Record<SuitType, SuitOptionType> =
{ "Hearts": { icon: "♥️" },
...etc }
and permits looping over the options in an order of your choosing, the way a numeric enum does, e.g. for showing a React element for each:
{Suits.map(suit => <SuitComponent key={suit} suit={suit} />)}
Hope this changes your mind about the utility of union-of-values types!