What I've pushed for is simple, regular refactoring. Build it into whatever your release cycle is. Sprints? Every sprint involves a cleanup effort, doesn't have to be big, but something. Kanban? Try to make sure that X% (measured over some period of time) of your work is cleanup. Larger release cycles? Do the same thing, it doesn't need to be much but it needs to be constant. You skip it once, it's like skipping the gym for a week. The habit is broken, good luck getting back to it. And it's worse here, management will see an apparent improvement in output (because you skipped that cleanup for a reason, to achieve some other release goal). And it will become deprioritized.
Tech debt is the same - it allows for benefits sooner, but at a price later on.
Let's say you have a new idea. You can spent 10x effort to make version 1 perfect or 1x effort (with 9x technical debt) to make something good enough.
Sure it might have brittle code, sure it might crash a bit, sure the interface is a bit inconsistent, and there are no docs, but hey it works - does anyone care enough to pay got it?
The 1x approach gets to market fast, helps determine if there even _is_ a market at all.
If the project is successful then the tech debt has to be "paid" in re-architecting, refactoring and in some cases rewriting.
If it is unsuccessful then no harm done, just move on.
There's definitely a place in an early project for moving quickly, there's definitely a place in a mature project for moving slowly, but getting everything right. The real trick is figuring out when to switch - the later you do it the more debt you accumulate. Too soon and you waste resources that may be needed more critically elsewhere.
The big problem of course are places where they never pay down the debt - until the whole thing collapses, and you're best off just throwing it all away - which you can't do because there are a bunch of paying users so you just keep hobbling along.
Avoiding tech debt altogether is expensive in money and time. But assuming you have both of those, then yes, tech debt can be avoided. (at least for now, no-one can predict what new things might exist tomorrow.)
If you continuously work on the code, it will accumulate debt over time in the form of bugs, or design flaws when taking shortcuts implementing new behavior. The more people you have working in the same area, the likelier this is to occur.
The long term solution like one of the posters in another thread said, is to pay down your tech debt strategically over time. Good habits for preparing to deal with it are keeping tests updated, and commenting in sections that get particularly gnarly.