I mean yeah, you do end up constructing a write model to understand if a command is allowed. And having the model allows you to, if needed, express some of your rules as assertions on the model. In which case, you could express validation as:
If we assume the command is valid, and apply to the in-memory model the events that handling it would persist, will the resulting state of the model still fulfill all the invariants? If it does, persist the events, and consider the command successful.
There are some good properties to this, such as writing your invariants as assertions, and this automatically applying to all handlers.
But in practice it seems very brittle, since, once again, the "state" of an old entity might violate the currently checked invariants... which, while not great and probably requiring some thought, doesn't really need to fail commands that are orthogonal to the violated invariant.
Looking at a real world example, having an incorrectly-formatted phone number/billing address is "bad". But failing all transactions to/from the affected account until the issue is fixed, despite all the prerequisites specific to the transaction being met, is much worse.
And, of course, there are a lot more reasons to fail a command than "succeeding the command would put/leave the state in violation of an invariant". And these rules that apply to the command and not the state still need to share logic.
We're a place where coders share, stay up-to-date and grow their careers.
We strive for transparency and don't collect excess data.