diff --git a/compiler/gentype/TranslateTypeDeclarations.ml b/compiler/gentype/TranslateTypeDeclarations.ml index 2768bdf343..2ed90b6ec4 100644 --- a/compiler/gentype/TranslateTypeDeclarations.ml +++ b/compiler/gentype/TranslateTypeDeclarations.ml @@ -41,12 +41,20 @@ let create_case (label, attributes) ~poly = * If @genType.as is used, perform renaming conversion. * If @as is used (with records-as-objects active), escape and quote if * the identifier contains characters which are invalid as JS property names. + * For escaped identifiers like \"foo-bar", strip the surrounding \"..." + * since they are part of the ReScript syntax, not the actual field name. + * The resulting name will be quoted later in EmitType if needed. *) let rename_record_field ~attributes ~name = attributes |> Annotation.check_unsupported_gentype_as_renaming; match attributes |> Annotation.get_as_string with - | Some s -> s |> String.escaped - | None -> name + | Some s -> String.escaped s + | None -> + (* Strip surrounding \"..." from escaped identifiers like \"foo-bar" *) + let len = String.length name in + if len >= 3 && name.[0] = '\\' && name.[1] = '"' && name.[len - 1] = '"' + then String.sub name 2 (len - 3) + else name let traslate_declaration_kind ~config ~loc ~output_file_relative ~resolver ~type_attributes ~type_env ~type_name ~type_vars declaration_kind : diff --git a/tests/gentype_tests/typescript-react-example/src/EscapedNames.gen.tsx b/tests/gentype_tests/typescript-react-example/src/EscapedNames.gen.tsx new file mode 100644 index 0000000000..460be7821b --- /dev/null +++ b/tests/gentype_tests/typescript-react-example/src/EscapedNames.gen.tsx @@ -0,0 +1,20 @@ +/* TypeScript file generated from EscapedNames.res by genType. */ + +/* eslint-disable */ +/* tslint:disable */ + +import * as EscapedNamesJS from './EscapedNames.res.js'; + +export type variant = "Illegal\"Name"; + +export type polymorphicVariant = "Illegal\"Name"; + +export type object_ = { readonly normalField: number; readonly "escape\"me": number }; + +export type record = { + readonly normalField: variant; + readonly "Renamed'Field": number; + readonly "Illegal-field name": number +}; + +export const myRecord: record = EscapedNamesJS.myRecord as any; diff --git a/tests/gentype_tests/typescript-react-example/src/EscapedNames.res b/tests/gentype_tests/typescript-react-example/src/EscapedNames.res new file mode 100644 index 0000000000..2000c79e0e --- /dev/null +++ b/tests/gentype_tests/typescript-react-example/src/EscapedNames.res @@ -0,0 +1,21 @@ +@genType +type variant = | @as("Illegal\"Name") IllegalName + +@genType +type polymorphicVariant = [#"Illegal\"Name"] + +@genType +type object_ = {"normalField": int, "escape\"me": int} + +@genType +type record = { + normalField: variant, + @as("Renamed'Field") renamedField: int, + \"Illegal-field name": int, +} +@genType +let myRecord = { + normalField: IllegalName, + renamedField: 42, + \"Illegal-field name": 7, +} diff --git a/tests/gentype_tests/typescript-react-example/src/EscapedNames.res.js b/tests/gentype_tests/typescript-react-example/src/EscapedNames.res.js new file mode 100644 index 0000000000..109c107203 --- /dev/null +++ b/tests/gentype_tests/typescript-react-example/src/EscapedNames.res.js @@ -0,0 +1,13 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +let myRecord = { + normalField: "Illegal\"Name", + "Renamed'Field": 42, + "Illegal-field name": 7 +}; + +export { + myRecord, +} +/* No side effect */