Just use dynamic or better yet type-tag-free languages. Types are hard to get right and hard to reason about. Sure, there are some Sheldons out there who master it even under pasta applications, but most of us are not Sheldons. C# also bleeped up types by adding nullable types, making reflection into a scavenger hunt.
For dynamic or tag-free languages, type indicators could be used to parse-check scalar (base) values to see if they are interpretable as the intended type:
function foo(int a, date b) {...}
This would be equivalent to: function foo(a, b) {
if (! parsableAsInt(a)) throwTypeError(...);
if (! parsableAsDate(b)) throwTypeError(...);
}
And don't overload operators, such as how some languages use "+" to mean both arithmetic addition and string concatenation. Use a different symbol for concatenation like PHP does.