asm.js is proof that a compile-to-JS language doesn't necessarily have to discard the correctness of its number types. A statically typed language can do a lot. Integer values can be can to int32 via `| 0`, longs can be emulated with two numbers (GWT does this).
The tradeoff is speed, especially for dynamically typed languages. Having to check your operand types in JS before doing work is a performance killer.