New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support bigint literals in const enums #37783
Comments
Would take a PR to improve the error message but I don't understand the use case very much. What kind of enums would be backed by bigints? |
The use case would be the similar to using normal const enum IPv4Masks {
MulticastMask = 0x00_ff_ff_ff,
// ...
} But IPv6 addresses are 64-bit integers. So, because const enums don't support bigints, I'm unable to similarly do const enum IPv6Masks {
MulticastMask= 0x00ff_ffff_ffff_ffff_ffff_ffff_ffff_ffffn,
// ...
} You could also easily imagine large bitsets with >52 values. const enum Permissions {
Read = 1n << 0n,
Write = 1n << 1n,
// ...
BeFancy = 1n << 58n,
} I don't think there should be an error message at all here, since bigint literals are just another type of literal; restricting their use in const enums seems arbitrary. |
Since Numbers and BigInts don't mix, I'd vote to enforce the whole enum to be consistent: either all literals are Numbers, or all literals are BigInt. If there are no literals, but you'd like your enum to be BigInt-backed, you'd just add enum Foo {
CAT = 0n,
DOG, // 1n
OWL, // 2n
} |
Currently enums don't restrict that their values are consistent, for example this is valid: enum Foo {
Bar1 = 1,
Bar2 = 'hello',
Bar3 = true,
} |
Actually, >31 values, since bitwise operators in JS convert Number operands to signed 32-bit which makes the 32nd bit effectively unusable. Being able to use BigInts would be very helpful for interop with native code. |
Yes, supporting bigint allows more flags than 31 flags [1<<0, 1<<31, 1<<32] // [1, -2147483648, 1]
[1n<<0n, 1n<<31n, 1n<<32n] // [1n, 2147483648n, 4294967296n] |
Possible problem with bigint enums is ambiguous reverse mapping. For example, the following code will not work as expected: enum A {
a = 1,
b = 1n,
}
// Compiled to:
// A[A["a"] = 1] = "a";
// A[A["b"] = 1n] = "b";
// Expected: a
// Received: b
console.log(A[A.a]); Also, the expression I think, two solutions exist: Don’t emit reverse mappings for bigint membersJust like for string members:
Pros:
Cons:
Explicitly disambiguate enums with bigints using keywordAlso requires relaxing index type rules: bigint enum A {
a = 1, // Error.
b = 1n,
}
bigint enum B {
a = 1n,
}
console.log(B[B.b]); // 'a' Compiles to: // ...
A[A["a"] = 1] = "a";
A[A["b"] = 1n] = "b";
// ...
B[B["a"] = 1n] = "a";
// ...
console.log(B[B.b]); Pros:
Cons:
Another one: Only allow bigint members in const enumsConst enums are probably easier to implement as they don’t require reverse mappings. All we need is to allow Pros:
Cons:
Questions:
|
Also, reverse mapping for bigint members probably aren’t critical. These members most probably will be used for bit flags, where reverse mappings may not work even with regular numbers:
|
Here is a possible implementation of bigint const enums (assuming TSC host runtime supports bigints): miyaokamarina@1fbcc8e |
@miyaokamarina, I'd prefer just to have an error if bigint and non-bigint literals were mixed in an enum. |
@yseymour, I don't understand why this should be an error. Both const and non-const enums already allow mixed member types. Would it be an error, if string and bigint members mixed? I think, this behavior will be inconsistent with current enums behavior. Enums and especially const enums are underspecified after all, but I don't think this is a reason to add more strange behaviors. If enums will allow to explicitly specify underlying type, there will be no problem to warn about mixed types, but currently they don't. |
For example, underlying types may be specified either using leading keywords ( |
I just discovered this issue trying to create a constant enum for 64-bit permission bits. I would be helped by this feature. |
Ran into this problem when writing an enum for integrated circuit signal hold times (using process.hrtime.bigint() in Node). |
I am a long time C++ developer and am now helping out with the backend which is written in typescript. I too would like to see bigint supported in enums for the purpose of replacing defined constants with bitmasks. |
Please fix this 🙏 |
In TS 5.0 the reported error message was changed but arguably to an equally confusing one :p
The change wasn't really targeting this case anyhow, just noting this down here in case I decide to improve this error message anyhow. |
As previously stated by others, this feature would be useful for representing sets of bit flags larger than |
Search Terms
Suggestion
A bigint literal is a literal, but it does not seem usable in const enums.
Currently produces, on 3.9.0-beta:
Use Cases
Bigint compile-time constants 🙂
Examples
Should compile to
And log
123n
when run.Checklist
My suggestion meets these guidelines:
The text was updated successfully, but these errors were encountered: