(This was originally an answer I wrote at Drupal Answers, but I revised it, and decided this would be a good post for my Random Thoughts).
At work and home, I have a hodgepodge of Drupal 7 and Drupal 8 sites. To manage the Drupal 7 sites, I need Drush 8. My Drupal 8 projects tend to be at various versions (eg, security updates get done promptly, but internal sites are on different maintenance schedule than external and client sites), and are all built using drupal-composer. I also use Drupal Console and composer based tools for local development. Drush Launcher and similar wrappers work, but not all composer-based executables have them. I handle the situation in a different manner.
I keep a copy of Drush from Github, and fetch and checkout the latest 8.X.Y tag periodically. This executable is on my bash path. I do this on my local machine, and on my servers.
For drupal-composer projects, I use direnv, and then put the following in my
When you cd into the working directory for a project, the local vendor/bin gets prepended to PS1, and then that version of drush gets used instead of the global one. This lets me use Drush 9 for newer projects, and when combined with webflo/drupal-core-strict and webflo/drupal-core-require-dev you can avoid most dependency problems.
This approach also allows better control of all composer-based executables like phpunit; they gets added to the path and will pull in the same dependencies, and avoid update issues. It also works with anything that has per-project executables.