Or is there another way?
The answer to that question is that you need to understand the intention of the advice, because then you can see which kinds of solutions are valid solutions to the problem that the advice tries to fix.
The issue with magic strings is that developers have to know the right value to use. Use the wrong value, and it won't work Maybe there's a synonymous phrase that sounds just as valid (but isn't checked for), maybe the developer makes a non-obvious typo, ... whatever the reason is, using magic strings is something that forces the developer to either remember these strings exactly or constantly look up the correct string.
If you can provide a way for the developer to not have to remember the exact string, instead being able to select it from a premade list, then you've solved the core problem.
IntelliSense is a very common solution here. If you can make the options available via IntelliSense, then the developer can easily select the right option.
There are a few ways to achieve this. Creating specific methods (your solution) is one way. Another way could be to introduce an enum-like object that maps the magic strings to fields on the object, so a developer could do something like:
object.on(EventNames.Click, function handler() {});
object.on(EventNames.Hover, function handler() {});
object.on(EventNames.MyCustomEvent, function handler() {});
This solved the problem without needing you to redesign how JS designed its magic-string method syntax (which was a bad call by whoever designed it to be this way).
There are non-IntelliSense solutions to this as well, e.g. if your IDE has code-generating templates so you can have the dev render a specific type of handler. This is a bit more IDE-specific though and it only really helps you in creating new handlers, not so much in making changes to existing handlers.
That being said, Javascript does not have any sense of strong typing, so you can't reasonably expect the system to point out every mistake to you. This is the nature of JS and you can't fully fix that.
As long as your solution gives the developer some nice way to autocomplete the value without needing to remember the string by heart and manually type it; that's an improvement.
I'm not sure what javascript being dynamically typed has to do with this.
-- The primary benefit of your pattern is so that a compiler can check the static types to make sure they line up. That doesn't happen in JavaScript..on('string', handler)
then I guess I will just use that.on(bobEvent(...))
.