You have identified the exact failure, and it has a well-established answer: do not validate before the input could reasonably be complete.
The email field is the clearest case. Every valid address passes through a long sequence of invalid states on the way to being typed. Showing an error during that sequence is not information, the user knows they have not finished, it is just noise, and worse, it trains people to ignore the error area entirely. By the time you have a real error to show, the red text has become furniture.
The standard pattern that avoids this:
- Validate on blur, when focus leaves the field. That is the earliest moment at which "incomplete" and "wrong" are distinguishable.
- Once a field has shown an error, re-validate on every keystroke. Now live feedback is genuinely helpful, because the user is trying to fix a specific thing and wants to know the instant they have.
That asymmetry is the whole trick. Late on the first error, immediate on every correction.