I can recommend "Domain Modeling Made Functional" by Scott Wlaschin presented at KanDDDinsky 2019, that offers a very appealing example for making making invalid states unrepresentable. The example code is in F# but that is a perfect language to demonstrate the general idea. Best-practice I guess boils down to finding the right balance throughout the application design.

https://www.youtube.com/watch?v=2JB1_e5wZmU