-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Proposal: Merge enum and const enum features #6695
Comments
What happens if someone wants a |
Good call. The Or a Symbol may be used instead. |
I want to first go back to the original problems you outlined to make sure we would be solving them in the least disruptive way.
I don't understand this claim. Given this code: enum E { a, b, c }
let x = E['a']; // x: E, x = 0
let s = Math.random() > 0.5 ? 'b' : '1';
let y = E[s]; // y: any, coerce to number if you're sure about s So there's already a mechanism in place to convert from strings to numbers. It's an intentional safeguard that indexing by a
This is a bit like phrasing "abstract classes can't be instantiated" as a problem -- one of the key features of
Can you clarify what this means? It's intentional that two arbitrary enums aren't considered compatible. |
Sure: re. (1):
See this example: enum E { a, b, c }
const a :number = E["a"]; results in this TSC error message:
So one cannot actually use a The reason for using TypeScript is using types. Forcing an re. (2):
It sure is. But it's unnecessary to introduce a new type for them. The standard `enum` type can handle these cases as well (see my examples). One cannot export or display See the TypeScript project, for example: There are loads of The core issue is: Would it be preferable to change these I don't see a reason for re. (3):
That's my conclusion from the user story I'm facing: being able to export the current TypeScript `const enum` values into a generated `tsconfig.json` file and to provide sensibel error messages. From within the context of the program itself one might only need My statement was meant on a metaphysical level. I believe my proposal solves this challenge by having the advantages of both, |
I actually came here to look for some answers regarding a different enum scenario, but the string to number conversion for enum actually works fine for me on 1.7.6
which generates
|
@mykohsu : That's because in your TSC configuration (e.g. If you set TSC to strict mode (i.e. require strong typing) by setting the above option to |
Still works |
@mykohsu : Good observation! I can only suspect that this is a strange special treatment of constant index expressions. While this indeed works: enum E { a, b, c }
const a :number = E["a"]; ... this doesn't: enum E { a, b, c }
const s = "b";
const a :number = E[s]; |
Indexing by a string literal produces the property with the same name. When there's indirection involved, we can't detect this, but I think this will be changing at some point with string literal types when the expression is a string-initialized |
That's something we're considering - #6080 is the closest thing that tracks it. I don't think we should change the indexing behavior, but I do think the fact that you can't internally use a const enum and externally expose a runtime-dependent API is a problem, and it's a problem that we've run into in the compiler itself. The way we get around this is entirely a hack - we use |
Is there any progress on this? |
it is marked as "Needs Proposal", so we are looking for a detailed proposal for the feature. Please see Writing Good Design Proposals. |
😲 Isn't my proposal above, which is rather detailed, sufficient? It contains all the use cases there are. |
We are looking for a little bit more details. things you would think about if you were to sit down and implement it today. |
would be really great to have this feature someday |
Anyone want to continue this issue? |
In the eve of TypeScript 3.0, can anyone at the TypeScript team create a proposal for this? |
ping |
Do you know why this issue isn't listed when looking for issues? Currently no-one will find it and work on it. |
Hey @SetTrend please vote using 👍 or 👎 rather than pinging subscribers of the issue. The team prioritizes based on general demand, and proposals are welcomed by the community. |
Hi @DanielRosenwasser , the issue with this issue is (or better: "was" as my ping seems to have fixed this now): This issue isn't (wasn't) found anymore (see my previous comment). Things cannot be voted upon if they are not found. |
Not sure what you're running into but it comes up when searching for "merge enum" https://github.com/Microsoft/TypeScript/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+merge+enum |
Currently there are two enumerable types specified in TypeScript:
enum
andconst enum
.Both of them aren't bijective, i.e. they both don't provide the ability to cast them arbitrarily and unambiguously between
string
,number
andenum
.After discussing this on Gitter with @jsobell and @masaeedu I'd like to propose the following:
const enum
on constant index expressions andenum
on variable enum expressions.number
value when astring
index expression is used on anenum
.number
andstring
values, to be used as index argument types on the proposed mergedenum
type.This would solve some major problems with the current design. Currently ...
enum
values cannot be converted to theirnumber
equivalent, only to theirstring
representation.const enum
values cannot be converted to theirstring
representation, only to theirnumber
equivalent.(This blocks
const enum
values from being used to serialize configuration settings into a commonly expected string value representation.)const enum
values can not be converted toenum
values and vice versa.The key to providing the missing functionality is type inference. At compile time, TSC is able to tell whether a string or a number value is provided in an
enum
index argument. It's also able to tell whether the index expression is a constant or a variable.Given these prerequisites the compiler can easily decide ...
const enum
value or anenum
in the generated code,(Variable index expressions of type any should be regarded as values of type
string
.This will result in maximum compatibility.)So I'm proposing the following:
string
indexer expression on anenum
shall return anumber
if the type of the L-value isn't the enum itself:enum[:string] => number
.string
indexer expression on anenum
shall return anenum
if the type of the L-value is the enum itself:enum[:string] => E
.number
indexer expression on anenum
shall return astring
if the type of the L-value isn't the enum itself:enum[:number] => string
.number
indexer expression on anenum
shall return anenum
if the type of the L-value is the enum itself:enum[:number] => E
.enum
indexer expression on the sameenum
type shall return anumber
if the type of the L-value isn't the enum itself:enum[:enum] => number
. (During transpilation, this operation is practically redundant and may be cancelled from the output.)enum
indexer expression on the sameenum
type shall return anenum
if the type of the L-value is the enum itself:enum[:enum] => E
. (During transpilation, this operation is practically redundant and may be cancelled from the output.)string
ornumber
indexer expression on anenum
shall emit a constantnumber
value in JavaScript (i.e., this is theconst enum
equivalent).string
ornumber
indexter expression on anenum
shall emit an array indexer expression in JavaScript (i.e., this is theenum
equivalent).#### So, given the above prerequisites, here are two examples, hopefully shedding some light upon my proposal:
##### (A) Example illustrating type inference being used at compile time to decide whether to return a `number` or a `string` value from an enum:
The following TypeScript code:
... should result in the following JavaScript compilation result:
##### (B) Example illustrating `const enum` and `enum` being merged into one single type:
The following TypeScript code:
... should result in the following JavaScript compilation result:
Some of the `E[n] ? n : undefined` constructs may be cancelled if runtime boundary checking isn't wanted/desired (new boolean compiler option?). So `e = E[n] ? n : undefined;` may then be transpiled to `e = n;`.
In the discussion on Gitter I learned about #3507, #592. Yet I feel the above proposal will add value to the ongoing discussion on improving the `enum` types.
The text was updated successfully, but these errors were encountered: