Closed
Description
TypeScript Version: 3.8.3 (playground)
Search Terms:
- "parseInt any"
- "parseInit type"
- "parseInit string"
- "parseFloat any"
- "parseFloat type"
- "parseFloat string"
Code
const maybeNumber: number | string = 1;
// The issue: parseInt only accepts strings so this fails,
// even though the runtime happily accepts any value...
const asNumber1 = parseInt(maybeNumber, 10)
// So the solution would be:
// Convert the number toString() and the string toString() so we can be sure that we never
// pass numbers into the parseInt function...
const asNumber2 = parseInt(maybeNumber.toString(), 10)
// Or, better do a type check. But we are still duplicating a type check that already exits in the runtime... :/
const asNumber3 = typeof maybeNumber === 'string' ? parseInt(maybeNumber, 10) : maybeNumber
// Or simply accept defeat and out out
const asNumber4 = parseInt(maybeNumber as string, 10)
Expected behavior:
parseInt
and parseFloat
accepts any
.
The spec gives the function the signature parseInt ( string, radix )
but also states that the argument will be converted to string internally (Let inputString be ? ToString(string).
).
In my opinion, the type system should allow relaying on the behavior:
- It improves usability
- Adding runtime checks creates bigger bundles and slower code (even if only by a tiny margin)
IMHO duplicate type checks should not be encouraged.
Actual behavior:
The first parseInt
call returns the type error:
Argument of type 'string | number' is not assignable to parameter of type 'string'.
Type 'number' is not assignable to type 'string'.(2345)
Playground Link: here