How to translate a custom Constraint message?
The constraint system is one of the few places where string literals aren't directly wrapped in t(). One reason for this is probably because the variables which form the "context" and string replacements for the messages aren't directly available when defining the constraint. @see \Drupal\Core\Validation\DrupalTranslator.

So the answer is: core does this for you. You can see exactly where this happens in: \Drupal\Core\TypedData\Validation\ExecutionContext::addViolation.