Skip to content

Commit e81cffe

Browse files
patrickszmucerPatrick Szmucersvc-changelog
authored
[improvement] Generate more lenient enums (#170)
* [improvement] Generate more lenient enums * Remove commented out code * Add generated changelog entries * 'value as value' in order to make type inference better * Remove test directory * Revert build.gradle changes Co-authored-by: Patrick Szmucer <pszmucer@palantir.com> Co-authored-by: svc-changelog <svc-changelog@palantir.com>
1 parent cb6ad32 commit e81cffe

File tree

8 files changed

+86
-26
lines changed

8 files changed

+86
-26
lines changed

changelog/@unreleased/pr-170.v2.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
type: improvement
2+
improvement:
3+
description: Generate more lenient enums.
4+
links:
5+
- https://github.com/palantir/conjure-typescript/pull/170
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1-
export enum SimpleEnum {
2-
VALUE = "VALUE"
1+
export namespace SimpleEnum {
2+
export type VALUE = "VALUE";
3+
4+
export const VALUE = "VALUE" as "VALUE";
35
}
6+
7+
export type SimpleEnum = keyof typeof SimpleEnum;
Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,27 @@
1-
export enum DeprecatedEnumExample {
2-
ONE = "ONE",
1+
export namespace DeprecatedEnumExample {
2+
export type ONE = "ONE";
33
/**
44
* @deprecated use ONE
55
*/
6-
OLD_ONE = "OLD_ONE",
6+
export type OLD_ONE = "OLD_ONE";
77
/**
88
* You should no longer use this
99
*
1010
* @deprecated use ONE
1111
*/
12-
OLD_DEPRECATED_ONE = "OLD_DEPRECATED_ONE",
12+
export type OLD_DEPRECATED_ONE = "OLD_DEPRECATED_ONE";
1313
/**
1414
* You should no longer use this
1515
*
1616
* @deprecated should use ONE
1717
*
1818
*/
19-
OLD_DOCUMENTED_ONE = "OLD_DOCUMENTED_ONE"
19+
export type OLD_DOCUMENTED_ONE = "OLD_DOCUMENTED_ONE";
20+
21+
export const ONE = "ONE" as "ONE";
22+
export const OLD_ONE = "OLD_ONE" as "OLD_ONE";
23+
export const OLD_DEPRECATED_ONE = "OLD_DEPRECATED_ONE" as "OLD_DEPRECATED_ONE";
24+
export const OLD_DOCUMENTED_ONE = "OLD_DOCUMENTED_ONE" as "OLD_DOCUMENTED_ONE";
2025
}
26+
27+
export type DeprecatedEnumExample = keyof typeof DeprecatedEnumExample;

src/commands/generate/__tests__/resources/test-cases/example-types/product/enumExample.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,17 @@
22
* This enumerates the numbers 1:2 also 100.
33
*
44
*/
5-
export enum EnumExample {
6-
ONE = "ONE",
7-
TWO = "TWO",
5+
export namespace EnumExample {
6+
export type ONE = "ONE";
7+
export type TWO = "TWO";
88
/**
99
* Value of 100.
1010
*/
11-
ONE_HUNDRED = "ONE_HUNDRED"
11+
export type ONE_HUNDRED = "ONE_HUNDRED";
12+
13+
export const ONE = "ONE" as "ONE";
14+
export const TWO = "TWO" as "TWO";
15+
export const ONE_HUNDRED = "ONE_HUNDRED" as "ONE_HUNDRED";
1216
}
17+
18+
export type EnumExample = keyof typeof EnumExample;
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1-
export enum SimpleEnum {
2-
VALUE = "VALUE"
1+
export namespace SimpleEnum {
2+
export type VALUE = "VALUE";
3+
4+
export const VALUE = "VALUE" as "VALUE";
35
}
6+
7+
export type SimpleEnum = keyof typeof SimpleEnum;
Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
export enum EnumExample {
2-
ONE = "ONE",
3-
TWO = "TWO"
1+
export namespace EnumExample {
2+
export type ONE = "ONE";
3+
export type TWO = "TWO";
4+
5+
export const ONE = "ONE" as "ONE";
6+
export const TWO = "TWO" as "TWO";
47
}
8+
9+
export type EnumExample = keyof typeof EnumExample;
Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
/**
22
* Some documentation
33
*/
4-
export enum EnumWithDocs {
4+
export namespace EnumWithDocs {
55
/**
66
* Some field documentation
77
*/
8-
FOO = "FOO",
9-
BAR = "BAR"
8+
export type FOO = "FOO";
9+
export type BAR = "BAR";
10+
11+
export const FOO = "FOO" as "FOO";
12+
export const BAR = "BAR" as "BAR";
1013
}
14+
15+
export type EnumWithDocs = keyof typeof EnumWithDocs;

src/commands/generate/typeGenerator.ts

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,46 @@ export function generateType(
5050
/**
5151
* Generates a file of the following format:
5252
* ```
53-
* export type EnumExample = "ONE" | "TWO";
54-
* export const EnumExample = { ONE: "ONE" as "ONE", TWO: "TWO" as "TWO" };
53+
* export namespace EnumExample {
54+
* export type ONE = "ONE";
55+
* export type TWO = "TWO";
56+
*
57+
* export const ONE = "ONE" as "ONE";
58+
* export const TWO = "TWO" as "TWO";
59+
* }
60+
* export type EnumExample = keyof typeof EnumExample;
5561
* ```
62+
*
63+
* We do not use TypeScript Enums because they can not be assigned to an equivalent enum, making interop across
64+
* libraries more difficult
5665
*/
5766
export async function generateEnum(definition: IEnumDefinition, simpleAst: SimpleAst): Promise<void> {
5867
const sourceFile = simpleAst.createSourceFile(definition.typeName);
5968

60-
sourceFile.addEnum({
61-
docs: definition.docs != null ? [{ description: definition.docs }] : undefined,
69+
const namespaceDefinition = sourceFile.addNamespace({
6270
isExported: true,
63-
members: definition.values.map(enumValue => ({
64-
docs: addDeprecatedToDocs(enumValue),
71+
name: definition.typeName.name,
72+
typeAliases: definition.values.map(enumValue => ({
73+
isExported: true,
6574
name: enumValue.value,
66-
value: enumValue.value,
75+
type: doubleQuote(enumValue.value),
76+
docs: addDeprecatedToDocs(enumValue),
6777
})),
78+
bodyText: writer => {
79+
definition.values.forEach(({ value }) => {
80+
const quotedValue = doubleQuote(value);
81+
writer.writeLine(`export const ${value} = ${quotedValue} as ${quotedValue};`);
82+
});
83+
},
84+
});
85+
if (definition.docs != null) {
86+
namespaceDefinition.addJsDoc(definition.docs);
87+
}
88+
89+
sourceFile.addTypeAlias({
90+
isExported: true,
6891
name: definition.typeName.name,
92+
type: `keyof typeof ${definition.typeName.name}`,
6993
});
7094

7195
sourceFile.formatText();

0 commit comments

Comments
 (0)