|
35 | 35 | * <p>We will generate the following:
|
36 | 36 | *
|
37 | 37 | * <pre>{@code
|
38 |
| - * export enum TypedYesNo { |
| 38 | + * export const TypedYesNo = { |
39 | 39 | * YES: "YEP",
|
40 | 40 | * NO: "NOPE",
|
41 |
| - * } |
| 41 | + * } as const; |
| 42 | + * type TypedYesNo = typeof TypedYesNo[keyof typeof TypedYesNo]; |
42 | 43 | * }</pre>
|
43 | 44 | *
|
44 | 45 | * <p>Shapes that refer to this string as a member will use the following
|
@@ -87,22 +88,24 @@ private void generateUnnamedEnum() {
|
87 | 88 |
|
88 | 89 | // Named enums generate an actual enum type.
|
89 | 90 | private void generateNamedEnum() {
|
90 |
| - writer.writeDocs("@public") |
91 |
| - .openBlock("export enum $L {", "}", symbol.getName(), () -> { |
| 91 | + writer.writeDocs("@public\n@enum") |
| 92 | + .openBlock("export const $L = {", "} as const", symbol.getName(), () -> { |
92 | 93 | // Sort the named values to ensure a stable order and sane diffs.
|
93 | 94 | // TODO: Should we just sort these in the trait itself?
|
94 | 95 | enumTrait.getValues()
|
95 | 96 | .stream()
|
96 | 97 | .sorted(Comparator.comparing(e -> e.getName().get()))
|
97 | 98 | .forEach(this::writeNamedEnumConstant);
|
98 | 99 | });
|
| 100 | + writer.writeDocs("@public") |
| 101 | + .write("export type $L = typeof $L[keyof typeof $L]", symbol.getName(), symbol.getName(), symbol.getName()); |
99 | 102 | }
|
100 | 103 |
|
101 | 104 | private void writeNamedEnumConstant(EnumDefinition body) {
|
102 | 105 | assert body.getName().isPresent();
|
103 | 106 |
|
104 | 107 | String name = body.getName().get();
|
105 | 108 | body.getDocumentation().ifPresent(writer::writeDocs);
|
106 |
| - writer.write("$L = $S,", TypeScriptUtils.sanitizePropertyName(name), body.getValue()); |
| 109 | + writer.write("$L: $S,", TypeScriptUtils.sanitizePropertyName(name), body.getValue()); |
107 | 110 | }
|
108 | 111 | }
|
0 commit comments