Still, I think the TTY - and UARTS in general - have a lot of utility in this day and age, warty dragons and all. I've got a terminal server in my lab just for the case of wiring up the small, light, cheap, efficient embedded systems which still depend on the dragons to deliver the fire. Nothing quite like having a functional 9600-baud term you can tap into with an Oscilloscope and work out what the bits mean .. try doing that with a JSON-based interface. ;)
Further, there are still things for which there is not a right way to do it. If you look at the man page for "unbuffer" (part of expect), there's a "CAVEATS" section that describes a bug... that can't be fixed while PTYs are in their current state. I wouldn't call it "well and truly solved".
By 1994, GUIs were common on workstations, and hardware-based serial terminals were disappearing fast. OTOH, the command line as a UI paradigm is alive and well today and might well be around for another 20 or 40 years.
From modes to tty types to control chars and signals, the TTY system is itself a bloated relic whose stink becomes apparent when you try to connect it to the rest of the unix philosophy, where everything is supposed to be a stateless text stream.
This stuff is really interesting for historical reasons and made sense 20 years ago, but I long for the day where the TTY system is gone and character drivers work on some standard JSON stream or something.