Skip to content

Commit d9359b8

Browse files
committed
Remove special treatment of {x:option<t>} as optional field.
This is a breaking changes, but aligns more closely with TS. The two TS types: ```ts type t1 = { x?: string }; type t2 = { x: (undefined | string) }; ``` now correspond to the ReScript types: ```res @genType type t1 = {x?: string} @genType type t2 = {x: Js.undefined<string>} ``` The special treatment of fields of option type comes from a time where records with optional fields did not exist.
1 parent d2794d0 commit d9359b8

File tree

8 files changed

+41
-17
lines changed

8 files changed

+41
-17
lines changed

jscomp/gentype/TranslateSignatureFromTypes.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ let translateTypeDeclarationFromTypes ~config ~outputFileRelative ~resolver
1212
Log_.item "Translate Types.type_declaration %s\n" typeName;
1313
let declarationKind =
1414
match type_kind with
15-
| Type_record (labelDeclarations, _) ->
16-
TranslateTypeDeclarations.RecordDeclarationFromTypes labelDeclarations
15+
| Type_record (labelDeclarations, recordRepresentation) ->
16+
TranslateTypeDeclarations.RecordDeclarationFromTypes
17+
(labelDeclarations, recordRepresentation)
1718
| Type_variant constructorDeclarations
1819
when not
1920
(TranslateTypeDeclarations.hasSomeGADTLeaf constructorDeclarations)

jscomp/gentype/TranslateTypeDeclarations.ml

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
open GenTypeCommon
22

33
type declarationKind =
4-
| RecordDeclarationFromTypes of Types.label_declaration list
4+
| RecordDeclarationFromTypes of
5+
Types.label_declaration list * Types.record_representation
56
| GeneralDeclaration of Typedtree.core_type option
67
| GeneralDeclarationFromTypes of Types.type_expr option
78
(** As the above, but from Types not Typedtree *)
@@ -78,7 +79,12 @@ let traslateDeclarationKind ~config ~loc ~outputFileRelative ~resolver
7879
in
7980
{CodeItem.importTypes; exportFromTypeDeclaration}
8081
in
81-
let translateLabelDeclarations labelDeclarations =
82+
let translateLabelDeclarations ~recordRepresentation labelDeclarations =
83+
let isOptional l =
84+
match recordRepresentation with
85+
| Types.Record_optional_labels lbls -> List.mem l lbls
86+
| _ -> false
87+
in
8288
let fieldTranslations =
8389
labelDeclarations
8490
|> List.map (fun {Types.ld_id; ld_mutable; ld_type; ld_attributes} ->
@@ -111,7 +117,7 @@ let traslateDeclarationKind ~config ~loc ~outputFileRelative ~resolver
111117
->
112118
let optional, type1 =
113119
match type_ with
114-
| Option type1 -> (Optional, type1)
120+
| Option type1 when isOptional nameRE -> (Optional, type1)
115121
| _ -> (Mandatory, type_)
116122
in
117123
{mutable_; nameJS; nameRE; optional; type_ = type1})
@@ -196,9 +202,10 @@ let traslateDeclarationKind ~config ~loc ~outputFileRelative ~resolver
196202
in
197203
{translation with type_} |> handleGeneralDeclaration
198204
|> returnTypeDeclaration
199-
| RecordDeclarationFromTypes labelDeclarations, None ->
205+
| RecordDeclarationFromTypes (labelDeclarations, recordRepresentation), None
206+
->
200207
let {TranslateTypeExprFromTypes.dependencies; type_} =
201-
labelDeclarations |> translateLabelDeclarations
208+
labelDeclarations |> translateLabelDeclarations ~recordRepresentation
202209
in
203210
let importTypes =
204211
dependencies
@@ -227,7 +234,11 @@ let traslateDeclarationKind ~config ~loc ~outputFileRelative ~resolver
227234
|> TranslateTypeExprFromTypes.translateTypeExprsFromTypes
228235
~config ~typeEnv
229236
| Cstr_record labelDeclarations ->
230-
[labelDeclarations |> translateLabelDeclarations]
237+
[
238+
labelDeclarations
239+
|> translateLabelDeclarations
240+
~recordRepresentation:Types.Record_regular;
241+
]
231242
in
232243
let inlineRecord =
233244
match constructorArgs with
@@ -342,8 +353,8 @@ let translateTypeDeclaration ~config ~outputFileRelative ~recursive ~resolver
342353
in
343354
let declarationKind =
344355
match typ_type.type_kind with
345-
| Type_record (labelDeclarations, _) ->
346-
RecordDeclarationFromTypes labelDeclarations
356+
| Type_record (labelDeclarations, recordRepresentation) ->
357+
RecordDeclarationFromTypes (labelDeclarations, recordRepresentation)
347358
| Type_variant constructorDeclarations ->
348359
VariantDeclarationFromTypes constructorDeclarations
349360
| Type_abstract -> GeneralDeclaration typ_manifest

jscomp/gentype_tests/typescript-react-example/src/Core.gen.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ const CoreBS: any = CoreBS__Es6Import;
1313
// tslint:disable-next-line:interface-over-type-literal
1414
export type variant = "A" | { tag: "B"; value: string };
1515

16+
// tslint:disable-next-line:interface-over-type-literal
17+
export type t1 = { readonly x?: string };
18+
19+
// tslint:disable-next-line:interface-over-type-literal
20+
export type t2 = { readonly x: (undefined | string) };
21+
1622
export const null0: (x:(null | number)) => (null | number) = CoreBS.null0;
1723

1824
export const null1: (x:(null | number)) => (null | number) = CoreBS.null1;

jscomp/gentype_tests/typescript-react-example/src/Core.res

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,9 @@ let option0 = (x: option<string>) => x
6868

6969
@genType
7070
let option1 = (x: option<variant>) => x
71+
72+
@genType
73+
type t1 = {x?: string}
74+
75+
@genType
76+
type t2 = {x: Js.undefined<string>}

jscomp/gentype_tests/typescript-react-example/src/ImportJsValue.gen.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ import type {polyType as $$polyType} from './MyMath';
107107
import type {stringFunction as $$stringFunction} from './MyMath';
108108

109109
// tslint:disable-next-line:interface-over-type-literal
110-
export type point = { readonly x: number; readonly y?: number };
110+
export type point = { readonly x: number; readonly y: (undefined | number) };
111111

112112
// tslint:disable-next-line:interface-over-type-literal
113113
export type numberOrString = $$numberOrString;

jscomp/gentype_tests/typescript-react-example/src/Object.gen.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66
export type someType = { readonly crop?: string; readonly "fp-z"?: string };
77

88
// tslint:disable-next-line:interface-over-type-literal
9-
export type someType2 = { readonly crop?: string; readonly "fp-z"?: string };
9+
export type someType2 = { readonly crop: (undefined | string); readonly "fp-z": (undefined | string) };

jscomp/gentype_tests/typescript-react-example/src/Records.gen.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,21 @@ import type {list} from '../src/shims/RescriptPervasives.shim';
1616
export type coord = {
1717
readonly x: number;
1818
readonly y: number;
19-
readonly z?: number
19+
readonly z: (undefined | number)
2020
};
2121

2222
// tslint:disable-next-line:interface-over-type-literal
2323
export type person = {
2424
readonly name: string;
2525
readonly age: number;
26-
readonly address?: string
26+
readonly address: (undefined | string)
2727
};
2828

2929
// tslint:disable-next-line:interface-over-type-literal
3030
export type business = {
3131
readonly name: string;
32-
readonly owner?: person;
33-
readonly address?: string
32+
readonly owner: (undefined | person);
33+
readonly address: (undefined | string)
3434
};
3535

3636
// tslint:disable-next-line:interface-over-type-literal

jscomp/gentype_tests/typescript-react-example/src/VariantsWithPayload.res

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
type payload = {
22
x: int,
3-
y: option<string>,
3+
y?: string,
44
}
55

66
type withPayload = [

0 commit comments

Comments
 (0)