Incorrect TS type definition for protobuf enums
- Dominant language
- JavaScript
- Stars
- 9.3k
- Forks
- 802
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 5
Description
[Protobuf `enum`s](https://developers.google.com/protocol-buffers/docs/proto3#enum) are incorrectly types as [TypeScript `enum`s](https://www.typescriptlang.org/docs/handbook/enums.html). This is incorrect because TS enums map from item name to value __and__ from value to item name.
### Example
Proto file:
```protobuf
enum Tag {
WORD = 0;
WORD_FOR_QMARK = 1;
WORD_FOR_STAR = 2;
}
```
Generated JS:
```js
/**
* @enum {number}
*/
proto.Tag = {
WORD: 0,
WORD_FOR_QMARK: 1,
WORD_FOR_STAR: 2,
};
```
TypeScript definition (`.d.ts`)
```ts
export enum Tag {
WORD = 0,
WORD_FOR_QMARK = 1,
WORD_FOR_STAR = 2,
}
```
However, the type definition actually means [this](https://www.typescriptlang.org/play?#code/KYDwDg9gTgLgBMAdgVwLZwCoEMDmcDeAUHCXAOoDyASgCJwC8cADADTGmW0D6AYtVwEUAsgEEqAaQZwAjG1LlqNXvwDKGMVIBMbAL5A):
```js
export var Tag;
(function (Tag) {
Tag[Tag["WORD"] = 0] = "WORD";
Tag[Tag["WORD_FOR_QMARK"] = 1] = "WORD_FOR_QMARK";
Tag[Tag["WORD_FOR_STAR"] = 2] = "WORD_FOR_STAR";
})(Tag || (Tag = {}));
```
... which is equivalent to:
```js
export var Tag = {
"0": "WORD",
"1": "WORD_FOR_QMARK",
"2": "WORD_FOR_STAR",
"WORD": 0,
"WORD_FOR_QMARK": 1,
"WORD_FOR_STAR": 2,
};
```
### Possible solution
Use a `type` for enums (same as for `message`s):
```ts
export type Tag = {
WORD: 0,
WORD_FOR_QMARK: 1,
WORD_FOR_STAR: 2,
}
```
I also want to point out that [`const enum`](https://www.typescriptlang.org/docs/handbook/enums.html#const-enums)s are not the solution since TS will insert the values of `const enum`s at compile time. `const enum`s are meant for purely internal usage only and not for APIs.
Contributor guide
Assessment
This issue has not been assessed yet.