{BigInt,Number}.fromString
This proposal is at stage 1 of the TC39 process.
The BigInt
proposal initially included a static BigInt.parseInt
method. After some discussion, it was removed in favor of a separate proposal to add a static fromString
method to both BigInt
and Number
. This is that proposal.
{BigInt,Number}.prototype.toString(radix)
enables converting a numeric value into a string representation of that value. For BigInt
s specifically, there is currently no built-in way to do the inverse, i.e. to turn a string representation of a BigInt
with a given radix back into a BigInt
.
For Number
values, there is parseInt(string, radix = 10)
and Number.parseInt(string, radix = 10)
, but its behavior is suboptimal:
NaN
instead of throwing a SyntaxError
exception when string
does not represent a number.NaN
instead of throwing a RangeError
exception when radix
is not valid (i.e. radix !== 0 && radix < 2
or radix > 36
).0
, treating it as 10
instead, which does not make sense.0x
and 0X
but lacks support for octal integer literal prefixes 0o
and 0O
or binary integer literal prefixes 0b
and 0B
, which is inconsistent.parseInt
has some level of support for integer literal prefixes means that it’s not a clear counterpart to toString
.We propose extending both BigInt
and Number
with a new static fromString(string, radix = 10)
method which acts as the inverse of {BigInt,Number}.prototype.toString(radix = 10)
. It accepts only strings that can be produced by {BigInt,Number}.prototype.toString(radix = 10)
, and throws an exception for any other input.
Number.fromString('42');
// → 42
Number.fromString('42', 10);
// → 42
BigInt.fromString('42');
// → 42n
BigInt.fromString('42', 10);
// → 42n
The following examples use Number.fromString
. The semantics for BigInt.fromString
are identical except it returns a BigInt
rather than a Number
.
Unlike parseInt
, fromString
intentionally lacks special handling for integer literal prefixes.
Number.parseInt('0xc0ffee');
// → 12648430
Number.parseInt('0o755');
// → 0
Number.parseInt('0b00101010');
// → 0
Number.fromString('0xc0ffee');
// → SyntaxError
Number.fromString('0o755');
// → SyntaxError
Number.fromString('0b00101010');
// → SyntaxError
Number.fromString('C0FFEE', 16);
// → SyntaxError (toString produces lowercase digits)
Number.fromString('c0ffee', 16);
// → 12648430 === 0xc0ffee
Number.fromString('755', 8);
// → 493 === 0o755
Number.fromString('00101010', 2);
// → 42 === 0b00101010
Unlike parseInt
, fromString
throws a SyntaxError
exception when string
does not represent a number.
Number.parseInt('');
// → NaN
Number.parseInt(' \n ');
// → NaN
Number.parseInt('x');
// → NaN
Number.fromString('');
// → SyntaxError
Number.fromString(' \n ');
// → SyntaxError
Number.fromString('x');
// → SyntaxError
Unlike parseInt
, fromString
throws a RangeError
exception when radix < 2
or radix > 36
.
Number.parseInt('1234', 0);
// → 1234
Number.parseInt('1234', 1);
// → NaN
Number.parseInt('1234', 37);
// → NaN
Number.fromString('1234', 0);
// → RangeError
Number.fromString('1234', 1);
// → RangeError
Number.fromString('1234', 37);
// → RangeError
Unlike parseInt
, fromString
throws a TypeError
exception when string
is not a string.
Number.parseInt(true, 32);
// → 978894
Number.fromString(true, 32);
// → TypeError
fromString
intentionally lacks special handling for legacy octal integer literals, i.e. those without the explicit 0o
or 0O
prefix such as 010
. In other words, Number.fromString('010')
throws a SyntaxError
exception.
fromString
does not need to support numeric separators, as they cannot occur in {BigInt,Number}.prototype.toString(radix)
output. Number.fromString('1_000_000_000')
throws a SyntaxError
exception.
BigInt.fromString(string)
support the n
suffix?BigInt.fromString
does not need to support the n
suffix used for BigInt
literals, as it doesn’t occur in BigInt.prototype.toString(radix)
output. Furthermore, supporting it would introduce an ambiguity for radices where n
is a valid digit: should BigInt.fromString('1n', 32)
return 1
or 55
? With the current proposal, BigInt.fromString('1n', 32)
returns 55
, and BigInt.fromString('1n')
throws a SyntaxError
exception.