Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
- Fix `@val` shadowing (rewrite using `globalThis`). https://github.com/rescript-lang/rescript/pull/8098
- Fix `@scope` shadowing (rewrite using `globalThis`). https://github.com/rescript-lang/rescript/pull/8100
- Fix rewatch panic on duplicate module name. https://github.com/rescript-lang/rescript/pull/8102
- Fix gentype generating invalid syntax for exotic / escaped record field names and type names. https://github.com/rescript-lang/rescript/pull/8087

#### :memo: Documentation

Expand Down
2 changes: 1 addition & 1 deletion compiler/gentype/GenTypeCommon.ml
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ let ident ?(builtin = true) ?(type_args = []) name =
Ident {builtin; name; type_args}

let sanitize_type_name name =
name
name |> Ext_ident.unwrap_uppercase_exotic
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this fixes type \"UppercaseName" being emitted literally, breaking the typescript syntax

|> String.map (function
| '\'' -> '_'
| c -> c)
Expand Down
9 changes: 7 additions & 2 deletions compiler/gentype/TranslateTypeDeclarations.ml
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,15 @@ 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
| None -> name |> Ext_ident.unwrap_uppercase_exotic

let traslate_declaration_kind ~config ~loc ~output_file_relative ~resolver
~type_attributes ~type_env ~type_name ~type_vars declaration_kind :
Expand Down Expand Up @@ -290,7 +293,9 @@ let traslate_declaration_kind ~config ~loc ~output_file_relative ~resolver
create_variant ~inherits:[] ~no_payloads ~payloads ~polymorphic:false
~tag:tag_annotation ~unboxed:unboxed_annotation
in
let resolved_type_name = type_name |> TypeEnv.add_module_path ~type_env in
let resolved_type_name =
type_name |> sanitize_type_name |> TypeEnv.add_module_path ~type_env
in
let export_from_type_declaration =
{
CodeItem.export_type =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/* 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 UppercaseVariant = "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;
readonly UPPERCASE: number
};

export const myRecord: record = EscapedNamesJS.myRecord as any;
26 changes: 26 additions & 0 deletions tests/gentype_tests/typescript-react-example/src/EscapedNames.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@genType
type variant = | @as("Illegal\"Name") IllegalName

@genType
type \"UppercaseVariant" = | @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,
\"UPPERCASE": int,
}
@genType
let myRecord = {
normalField: IllegalName,
renamedField: 42,
\"Illegal-field name": 7,
\"UPPERCASE": 100,
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading