I validate at the point of use/when it matters.
For example if I'm going to use a value in a query, because I'm using parameterized queries the type conversion to string happens implicitly so type doesn't actually matter. If I get 2 or '2' it all ends up as '2' and the database infers type by the column type.
If I need something to be a integer and I don't trust the upstream system then you have to:
int(*number*)
At the end of the day if my JSON is going back to JavaScript I can't trust types either so I have to take the same precautions.