Skip to content
This repository was archived by the owner on Nov 13, 2023. It is now read-only.

Commit 6036bd9

Browse files
authored
Enums Christmas edition: support one object type, plus strings/booleans/integers. (#118)
* Enums Christmas edition: support strings, booleans, integers, and up to one object. * Only emit enums when there are no variants of unknown shape. * Check that the variant with payload has type object. The variant with payload is distinguished by checking typeof(...) = 'object'. So only emit enums if the payload has a type whose runtime representation is an object: records, objects, arrays, tuples. * Add running test for enums with payload. * README: complete documentation for Enums. * Add support for float constants in Enums. * README: float constants in Enums. * Consistencty.
1 parent 18d4d36 commit 6036bd9

23 files changed

+657
-175
lines changed

README.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -348,12 +348,18 @@ A file can export many components by defining them in sub-modules. The toplevel
348348

349349
### enums
350350

351-
Enums are Reason polymorphic variants without payload: essentially flat sequences of identifiers. E.g. type `` [ | `monday | `tuesday ] ``.
351+
Enums are Reason polymorphic variants without payload: essentially flat sequences of identifiers. E.g. type ``[@genType] type days = [ | `monday | `tuesday ] ``.
352352
The corresponding JS representation is `"monday"`, `"tuesday"`.
353353

354-
The `@genType.as` annotation can be used to change the name of an element on the JS side of things. So e.g. `` [ | [@genType.as "type"] `type_ ] `` exports Reason value `` `type_ `` to JS value `"type"`.
354+
The `@genType.as` annotation can be used to change the name of an element on the JS side of things. So e.g. ``` [ | [@genType.as "type"] `type_ ] ``` exports Reason value `` `type_ `` to JS value `"type"`.
355+
Boolean/integer/float constants can be expressed as ``` | [@genType.as true] `True ``` and ``` | [@genType.as 20] `Twenty ``` and ``` | [@genType.as 0.5] `Half ```.
355356

356-
See for example [Enums.re](examples/typescript-react-example/src/Enums.re).
357+
At most one variant can have a payload, which must have object type, e.g.
358+
``` [ | `unnamed | `named({. "name": string, "surname": string}) ] ```. Object types are arrays, objects, records and tuples.
359+
360+
See for example [Enums.re](examples/typescript-react-example/src/Enums.re) and [EnumsWithPayload.re](examples/typescript-react-example/src/EnumsWithPayload.re).
361+
362+
**NOTE** When exporting/importing values that use enum types, you have to use type annotations for enums, and cannot rely on type inference. So instead of ```let monday = `monday```, use ```let monday : days = `monday```. The former does not work, as the type checker infers a tyoe without annotations.
357363

358364
### imported types
359365

examples/flow-react-example/src/Enums.gen.js

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,27 @@
44
* @nolint
55
*/
66

7-
const $$toRE175361521 = {"type": 449540197, "module": -134553037, "XXX THIS IS DIFFERENT": 23437694};
7+
const $$toJS1061900109 = {"120": "x", "26810": "same"};
88

9-
const $$toJS18951405 = {"449540197": "type", "-134553037": "module", "23437694": "42"};
9+
const $$toRE694113598 = {"saturday": -29784519, "sunday": 569248848};
1010

11-
const $$toRE396727132 = {"monday": -949852400, "tuesday": 323181965, "wednesday": -863289194, "thursday": 122883354, "friday": 835226847, "saturday": -29784519, "sunday": 569248848};
11+
const $$toRE1061900109 = {"x": 120, "same": 26810};
1212

13-
const $$toJS98879741 = {"120": "x", "26810": "same"};
13+
const $$toJS584768163 = {"449540197": "type", "-134553037": "module", "23437694": "XXX THIS IS DIFFERENT"};
1414

15-
const $$toRE98879741 = {"x": 120, "same": 26810};
15+
const $$toJS930788378 = {"120": "x", "26809": "same"};
1616

17-
const $$toRE18951405 = {"type": 449540197, "module": -134553037, "42": 23437694};
17+
const $$toJS508922110 = {"449540197": "type", "-134553037": "module", "23437694": "42"};
1818

19-
const $$toJS149274715 = {"120": "x", "26809": "same"};
19+
const $$toRE930788378 = {"x": 120, "same": 26809};
2020

21-
const $$toRE916593523 = {"saturday": -29784519, "sunday": 569248848};
21+
const $$toRE508922110 = {"type": 449540197, "module": -134553037, "42": 23437694};
2222

23-
const $$toJS916593523 = {"-29784519": "saturday", "569248848": "sunday"};
23+
const $$toRE584768163 = {"type": 449540197, "module": -134553037, "XXX THIS IS DIFFERENT": 23437694};
2424

25-
const $$toRE149274715 = {"x": 120, "same": 26809};
25+
const $$toJS694113598 = {"-29784519": "saturday", "569248848": "sunday"};
2626

27-
const $$toJS175361521 = {"449540197": "type", "-134553037": "module", "23437694": "XXX THIS IS DIFFERENT"};
27+
const $$toRE288839514 = {"monday": -949852400, "tuesday": 323181965, "wednesday": -863289194, "thursday": 122883354, "friday": 835226847, "saturday": -29784519, "sunday": 569248848};
2828

2929
// $FlowExpectedError: Reason checked type sufficiently
3030
import * as EnumsBS from './Enums.bs';
@@ -41,7 +41,7 @@ export type x1 = "x" | "same";
4141

4242
export type x2 = "x" | "same";
4343

44-
export const isWeekend: (weekday) => boolean = function _(Arg1) { const result = EnumsBS.isWeekend($$toRE396727132[Arg1]); return result };
44+
export const isWeekend: (weekday) => boolean = function _(Arg1) { const result = EnumsBS.isWeekend($$toRE288839514[Arg1]); return result };
4545

4646
export const monday: "monday" = "monday";
4747

@@ -51,20 +51,20 @@ export const sunday: "sunday" = "sunday";
5151

5252
export const onlySunday: ("sunday") => void = function _(Arg1) { const result = EnumsBS.onlySunday(/* sunday */569248848); return result };
5353

54-
export const swap: ("saturday" | "sunday") => "saturday" | "sunday" = function _(Arg1) { const result = EnumsBS.swap($$toRE916593523[Arg1]); return $$toJS916593523[result] };
54+
export const swap: ("saturday" | "sunday") => "saturday" | "sunday" = function _(Arg1) { const result = EnumsBS.swap($$toRE694113598[Arg1]); return $$toJS694113598[result] };
5555

56-
export const testConvert: (testGenTypeAs) => testGenTypeAs = function _(Arg1) { const result = EnumsBS.testConvert($$toRE18951405[Arg1]); return $$toJS18951405[result] };
56+
export const testConvert: (testGenTypeAs) => testGenTypeAs = function _(Arg1) { const result = EnumsBS.testConvert($$toRE508922110[Arg1]); return $$toJS508922110[result] };
5757

58-
export const fortytwoOK: testGenTypeAs = $$toJS18951405[EnumsBS.fortytwoOK];
58+
export const fortytwoOK: testGenTypeAs = $$toJS508922110[EnumsBS.fortytwoOK];
5959

6060
export const fortytwoBAD: "fortytwo" = "fortytwo";
6161

62-
export const testConvert2: (testGenTypeAs2) => testGenTypeAs2 = function _(Arg1) { const result = EnumsBS.testConvert2($$toRE18951405[Arg1]); return $$toJS18951405[result] };
62+
export const testConvert2: (testGenTypeAs2) => testGenTypeAs2 = function _(Arg1) { const result = EnumsBS.testConvert2($$toRE508922110[Arg1]); return $$toJS508922110[result] };
6363

64-
export const testConvert3: (testGenTypeAs3) => testGenTypeAs3 = function _(Arg1) { const result = EnumsBS.testConvert3($$toRE175361521[Arg1]); return $$toJS175361521[result] };
64+
export const testConvert3: (testGenTypeAs3) => testGenTypeAs3 = function _(Arg1) { const result = EnumsBS.testConvert3($$toRE584768163[Arg1]); return $$toJS584768163[result] };
6565

66-
export const testConvert2to3: (testGenTypeAs2) => testGenTypeAs3 = function _(Arg1) { const result = EnumsBS.testConvert2to3($$toRE18951405[Arg1]); return $$toJS175361521[result] };
66+
export const testConvert2to3: (testGenTypeAs2) => testGenTypeAs3 = function _(Arg1) { const result = EnumsBS.testConvert2to3($$toRE508922110[Arg1]); return $$toJS584768163[result] };
6767

68-
export const id1: (x1) => x1 = function _(Arg1) { const result = EnumsBS.id1($$toRE149274715[Arg1]); return $$toJS149274715[result] };
68+
export const id1: (x1) => x1 = function _(Arg1) { const result = EnumsBS.id1($$toRE930788378[Arg1]); return $$toJS930788378[result] };
6969

70-
export const id2: (x2) => x2 = function _(Arg1) { const result = EnumsBS.id2($$toRE98879741[Arg1]); return $$toJS98879741[result] };
70+
export const id2: (x2) => x2 = function _(Arg1) { const result = EnumsBS.id2($$toRE1061900109[Arg1]); return $$toJS1061900109[result] };

examples/flow-react-example/src/EnumsWithPayload.bs.js

Lines changed: 42 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* @flow strict
3+
* @generated
4+
* @nolint
5+
*/
6+
7+
const $$toJS542320962 = {"97": "a", "98": "bRenamed", "937218926": true, "-574635695": 20, "803296723": 0.5};
8+
9+
const $$toRE542320962 = {"a": 97, "bRenamed": 98, "true": 937218926, "20": -574635695, "0.5": 803296723};
10+
11+
// $FlowExpectedError: Reason checked type sufficiently
12+
import * as EnumsWithPayloadBS from './EnumsWithPayload.bs';
13+
14+
export type payload = {|+x: number, +y?: string|};
15+
16+
export type withPayload = "a" | "bRenamed" | true | 20 | 0.5 | payload;
17+
18+
export const testWithPayload: (withPayload) => withPayload = function _(Arg1) { const result = EnumsWithPayloadBS.testWithPayload((typeof(Arg1) === 'object' ? [/* c */99, [Arg1.x, Arg1.y]] : $$toRE542320962[Arg1.toString()])); return (typeof(result) === 'object' ? {x:result[1][0], y:result[1][1]} : $$toJS542320962[result]) };
19+
20+
export const printEnumValue: (withPayload) => void = function _(Arg1) { const result = EnumsWithPayloadBS.printEnumValue((typeof(Arg1) === 'object' ? [/* c */99, [Arg1.x, Arg1.y]] : $$toRE542320962[Arg1.toString()])); return result };
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
type payload = {
2+
x: int,
3+
y: option(string),
4+
};
5+
6+
type withPayload = [
7+
| `a
8+
| [@genType.as "bRenamed"] `b
9+
| [@genType.as true] `True
10+
| [@genType.as 20] `Twenty
11+
| [@genType.as 0.5] `Half
12+
| `c(payload)
13+
];
14+
15+
[@genType]
16+
let testWithPayload = (x: withPayload) => x;
17+
18+
[@genType]
19+
let printEnumValue = (x: withPayload) =>
20+
switch (x) {
21+
| `a => Js.log("printEnumValue: a")
22+
| `b => Js.log("printEnumValue: b")
23+
| `True => Js.log("printEnumValue: True")
24+
| `Twenty => Js.log("printEnumValue: Twenty")
25+
| `Half => Js.log("printEnumValue: Half")
26+
| `c(payload) => Js.log4("printEnumValue x:", payload.x, "y:", payload.y)
27+
};
Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
/* TypeScript file generated by genType. */
22

3-
const $$toRE175361521 = {"type": 449540197, "module": -134553037, "XXX THIS IS DIFFERENT": 23437694};
3+
const $$toJS1061900109 = {"120": "x", "26810": "same"};
44

5-
const $$toJS18951405 = {"449540197": "type", "-134553037": "module", "23437694": "42"};
5+
const $$toRE694113598 = {"saturday": -29784519, "sunday": 569248848};
66

7-
const $$toRE396727132 = {"monday": -949852400, "tuesday": 323181965, "wednesday": -863289194, "thursday": 122883354, "friday": 835226847, "saturday": -29784519, "sunday": 569248848};
7+
const $$toRE1061900109 = {"x": 120, "same": 26810};
88

9-
const $$toJS98879741 = {"120": "x", "26810": "same"};
9+
const $$toJS584768163 = {"449540197": "type", "-134553037": "module", "23437694": "XXX THIS IS DIFFERENT"};
1010

11-
const $$toRE98879741 = {"x": 120, "same": 26810};
11+
const $$toJS930788378 = {"120": "x", "26809": "same"};
1212

13-
const $$toRE18951405 = {"type": 449540197, "module": -134553037, "42": 23437694};
13+
const $$toJS508922110 = {"449540197": "type", "-134553037": "module", "23437694": "42"};
1414

15-
const $$toJS149274715 = {"120": "x", "26809": "same"};
15+
const $$toRE930788378 = {"x": 120, "same": 26809};
1616

17-
const $$toRE916593523 = {"saturday": -29784519, "sunday": 569248848};
17+
const $$toRE508922110 = {"type": 449540197, "module": -134553037, "42": 23437694};
1818

19-
const $$toJS916593523 = {"-29784519": "saturday", "569248848": "sunday"};
19+
const $$toRE584768163 = {"type": 449540197, "module": -134553037, "XXX THIS IS DIFFERENT": 23437694};
2020

21-
const $$toRE149274715 = {"x": 120, "same": 26809};
21+
const $$toJS694113598 = {"-29784519": "saturday", "569248848": "sunday"};
2222

23-
const $$toJS175361521 = {"449540197": "type", "-134553037": "module", "23437694": "XXX THIS IS DIFFERENT"};
23+
const $$toRE288839514 = {"monday": -949852400, "tuesday": 323181965, "wednesday": -863289194, "thursday": 122883354, "friday": 835226847, "saturday": -29784519, "sunday": 569248848};
2424

2525
// tslint:disable-next-line:no-var-requires
2626
const EnumsBS = require('./Enums.bs');
@@ -43,7 +43,7 @@ export type x1 = "x" | "same";
4343
// tslint:disable-next-line:interface-over-type-literal
4444
export type x2 = "x" | "same";
4545

46-
export const isWeekend: (_1:weekday) => boolean = function _(Arg1: any) { const result = EnumsBS.isWeekend($$toRE396727132[Arg1]); return result };
46+
export const isWeekend: (_1:weekday) => boolean = function _(Arg1: any) { const result = EnumsBS.isWeekend($$toRE288839514[Arg1]); return result };
4747

4848
export const monday: "monday" = "monday";
4949

@@ -53,20 +53,20 @@ export const sunday: "sunday" = "sunday";
5353

5454
export const onlySunday: (_1:"sunday") => void = function _(Arg1: any) { const result = EnumsBS.onlySunday(/* sunday */569248848); return result };
5555

56-
export const swap: (_1:"saturday" | "sunday") => "saturday" | "sunday" = function _(Arg1: any) { const result = EnumsBS.swap($$toRE916593523[Arg1]); return $$toJS916593523[result] };
56+
export const swap: (_1:"saturday" | "sunday") => "saturday" | "sunday" = function _(Arg1: any) { const result = EnumsBS.swap($$toRE694113598[Arg1]); return $$toJS694113598[result] };
5757

58-
export const testConvert: (_1:testGenTypeAs) => testGenTypeAs = function _(Arg1: any) { const result = EnumsBS.testConvert($$toRE18951405[Arg1]); return $$toJS18951405[result] };
58+
export const testConvert: (_1:testGenTypeAs) => testGenTypeAs = function _(Arg1: any) { const result = EnumsBS.testConvert($$toRE508922110[Arg1]); return $$toJS508922110[result] };
5959

60-
export const fortytwoOK: testGenTypeAs = $$toJS18951405[EnumsBS.fortytwoOK];
60+
export const fortytwoOK: testGenTypeAs = $$toJS508922110[EnumsBS.fortytwoOK];
6161

6262
export const fortytwoBAD: "fortytwo" = "fortytwo";
6363

64-
export const testConvert2: (_1:testGenTypeAs2) => testGenTypeAs2 = function _(Arg1: any) { const result = EnumsBS.testConvert2($$toRE18951405[Arg1]); return $$toJS18951405[result] };
64+
export const testConvert2: (_1:testGenTypeAs2) => testGenTypeAs2 = function _(Arg1: any) { const result = EnumsBS.testConvert2($$toRE508922110[Arg1]); return $$toJS508922110[result] };
6565

66-
export const testConvert3: (_1:testGenTypeAs3) => testGenTypeAs3 = function _(Arg1: any) { const result = EnumsBS.testConvert3($$toRE175361521[Arg1]); return $$toJS175361521[result] };
66+
export const testConvert3: (_1:testGenTypeAs3) => testGenTypeAs3 = function _(Arg1: any) { const result = EnumsBS.testConvert3($$toRE584768163[Arg1]); return $$toJS584768163[result] };
6767

68-
export const testConvert2to3: (_1:testGenTypeAs2) => testGenTypeAs3 = function _(Arg1: any) { const result = EnumsBS.testConvert2to3($$toRE18951405[Arg1]); return $$toJS175361521[result] };
68+
export const testConvert2to3: (_1:testGenTypeAs2) => testGenTypeAs3 = function _(Arg1: any) { const result = EnumsBS.testConvert2to3($$toRE508922110[Arg1]); return $$toJS584768163[result] };
6969

70-
export const id1: (_1:x1) => x1 = function _(Arg1: any) { const result = EnumsBS.id1($$toRE149274715[Arg1]); return $$toJS149274715[result] };
70+
export const id1: (_1:x1) => x1 = function _(Arg1: any) { const result = EnumsBS.id1($$toRE930788378[Arg1]); return $$toJS930788378[result] };
7171

72-
export const id2: (_1:x2) => x2 = function _(Arg1: any) { const result = EnumsBS.id2($$toRE98879741[Arg1]); return $$toJS98879741[result] };
72+
export const id2: (_1:x2) => x2 = function _(Arg1: any) { const result = EnumsBS.id2($$toRE1061900109[Arg1]); return $$toJS1061900109[result] };

examples/typescript-react-example/src/EnumsWithPayload.bs.js

Lines changed: 42 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/* TypeScript file generated by genType. */
2+
3+
const $$toJS542320962 = {"97": "a", "98": "bRenamed", "937218926": true, "-574635695": 20, "803296723": 0.5};
4+
5+
const $$toRE542320962 = {"a": 97, "bRenamed": 98, "true": 937218926, "20": -574635695, "0.5": 803296723};
6+
7+
// tslint:disable-next-line:no-var-requires
8+
const EnumsWithPayloadBS = require('./EnumsWithPayload.bs');
9+
10+
// tslint:disable-next-line:interface-over-type-literal
11+
export type payload = {readonly x: number, readonly y?: string};
12+
13+
// tslint:disable-next-line:interface-over-type-literal
14+
export type withPayload = "a" | "bRenamed" | true | 20 | 0.5 | payload;
15+
16+
export const testWithPayload: (_1:withPayload) => withPayload = function _(Arg1: any) { const result = EnumsWithPayloadBS.testWithPayload((typeof(Arg1) === 'object' ? [/* c */99, [Arg1.x, Arg1.y]] : $$toRE542320962[Arg1.toString()])); return (typeof(result) === 'object' ? {x:result[1][0], y:result[1][1]} : $$toJS542320962[result]) };
17+
18+
export const printEnumValue: (_1:withPayload) => void = function _(Arg1: any) { const result = EnumsWithPayloadBS.printEnumValue((typeof(Arg1) === 'object' ? [/* c */99, [Arg1.x, Arg1.y]] : $$toRE542320962[Arg1.toString()])); return result };
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
type payload = {
2+
x: int,
3+
y: option(string),
4+
};
5+
6+
type withPayload = [
7+
| `a
8+
| [@genType.as "bRenamed"] `b
9+
| [@genType.as true] `True
10+
| [@genType.as 20] `Twenty
11+
| [@genType.as 0.5] `Half
12+
| `c(payload)
13+
];
14+
15+
[@genType]
16+
let testWithPayload = (x: withPayload) => x;
17+
18+
[@genType]
19+
let printEnumValue = (x: withPayload) =>
20+
switch (x) {
21+
| `a => Js.log("printEnumValue: a")
22+
| `b => Js.log("printEnumValue: b")
23+
| `True => Js.log("printEnumValue: True")
24+
| `Twenty => Js.log("printEnumValue: Twenty")
25+
| `Half => Js.log("printEnumValue: Half")
26+
| `c(payload) => Js.log4("printEnumValue x:", payload.x, "y:", payload.y)
27+
};

examples/typescript-react-example/src/ImportJsValue.gen.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {area as areaNotChecked} from './MyMath';
66

77
import {useColor as useColorNotChecked} from './MyMath';
88

9-
const $$toJS479407683 = {"322339018": "tomato", "-999567389": "gray"};
9+
const $$toJS580645844 = {"322339018": "tomato", "-999567389": "gray"};
1010

1111
// In case of type error, check the type of 'round' in 'ImportJsValue.re' and './MyMath'.
1212
export const roundTypeChecked: (_1:number) => number = roundNotChecked;
@@ -24,7 +24,7 @@ export const area: unknown = function _(Arg1: any) { const result = areaTypeChec
2424
export const useColorTypeChecked: (_1:color) => number = useColorNotChecked;
2525

2626
// Export 'useColor' early to allow circular import from the '.bs.js' file.
27-
export const useColor: unknown = function _(Arg1: any) { const result = useColorTypeChecked($$toJS479407683[Arg1]); return result } as (_1:color) => number;
27+
export const useColor: unknown = function _(Arg1: any) { const result = useColorTypeChecked($$toJS580645844[Arg1]); return result } as (_1:color) => number;
2828

2929
// tslint:disable-next-line:no-var-requires
3030
const ImportJsValueBS = require('./ImportJsValue.bs');

0 commit comments

Comments
 (0)