@@ -91,11 +91,7 @@ auto TypeScript::operator()(const IRObject &entry) const -> void {
9191 return ;
9292 }
9393
94- if (has_additional) {
95- this ->output << " export type " << type_name << " = {\n " ;
96- } else {
97- this ->output << " export interface " << type_name << " {\n " ;
98- }
94+ this ->output << " export interface " << type_name << " {\n " ;
9995
10096 // We always quote property names for safety. JSON Schema allows any string
10197 // as a property name, but unquoted TypeScript/ECMAScript property names
@@ -115,32 +111,24 @@ auto TypeScript::operator()(const IRObject &entry) const -> void {
115111 }
116112
117113 if (has_additional) {
118- this ->output << " } & {\n " ;
119-
120- // While we could do this with the more idiomatic `Record<Exclude<string,
121- // X>, Y>`, we choose the more verbose manner in order to allow users to
122- // declare a type called `Record`
123- this ->output << " [K in string as K extends\n " ;
124-
125- std::size_t index{0 };
114+ // TypeScript index signatures must be a supertype of all property value
115+ // types. We use a union of all member types plus the additional properties
116+ // type plus undefined (for optional properties).
117+ this ->output << " [key: string]:\n " ;
126118 for (const auto &[member_name, member_value] : entry.members ) {
127- const auto is_last{index == entry.members .size () - 1 };
128- this ->output << " \" " << escape_string (member_name) << " \" " ;
129- if (!is_last) {
130- this ->output << " |" ;
131- }
132- this ->output << " \n " ;
133- ++index;
119+ this ->output << " "
120+ << sourcemeta::core::mangle (member_value.pointer ,
121+ this ->prefix )
122+ << " |\n " ;
134123 }
135-
136- this ->output << " ? never : K]: "
124+ this ->output << " "
137125 << sourcemeta::core::mangle (entry.additional ->pointer ,
138126 this ->prefix )
139- << " ;\n " ;
140- this ->output << " };\n " ;
141- } else {
142- this ->output << " }\n " ;
127+ << " |\n " ;
128+ this ->output << " undefined;\n " ;
143129 }
130+
131+ this ->output << " }\n " ;
144132}
145133
146134auto TypeScript::operator ()(const IRImpossible &entry) const -> void {
0 commit comments