For AI agents: the complete documentation index is available at /tc39-atlas/en/llms.txt, the full documentation bundle is available at /tc39-atlas/en/llms-full.txt, and this page is available as Markdown at /tc39-atlas/en/proposals/stage/1/proposal-number-fromstring.md.
  • English
  • {BigInt,Number}.fromString S1

    Proposal details
    Proposal overview

    This proposal introduces static fromString methods on Number and BigInt that reverse their toString methods, addressing the shortcomings of parseInt such as returning NaN for invalid input and lacking support for certain radixes. The proposed API throws appropriate errors (SyntaxError, RangeError, TypeError) for invalid strings, invalid radix, or non-string inputs, and deliberately ignores integer literal prefixes and separators.

    Note

    The README below comes from the upstream repository and may contain outdated stage or status metadata. Use the proposal details above as the current source of truth.

    ECMAScript proposal: {BigInt,Number}.fromString

    Status

    This proposal is at stage 1 of the TC39 process.

    Background

    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.

    Motivation

    {BigInt,Number}.prototype.toString(radix) enables converting a numeric value into a string representation of that value. For BigInts 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:

    • It returns NaN instead of throwing a SyntaxError exception when string does not represent a number.
    • It returns NaN instead of throwing a RangeError exception when radix is not valid (i.e. radix !== 0 && radix < 2 or radix > 36).
    • It accepts radix 0, treating it as 10 instead, which does not make sense.
    • It ignores leading whitespace and trailing non-digit characters.
    • It supports hexadecimal integer literal prefixes 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.
    • The fact that parseInt has some level of support for integer literal prefixes means that it’s not a clear counterpart to toString.

    Proposed solution

    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.

    High-level API

    Number.fromString('42');
    // → 42
    Number.fromString('42', 10);
    // → 42
    
    BigInt.fromString('42');
    // → 42n
    BigInt.fromString('42', 10);
    // → 42n

    Illustrative examples

    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

    FAQ

    What about legacy octal integers?

    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.

    What about numeric separators?

    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.

    Does 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.

    Specification

    Implementations

    • none yet