11#include < sourcemeta/codegen/generator.h>
22
3- #include < iomanip> // std::hex, std::setfill, std::setw
4- #include < sstream> // std::ostringstream
3+ #include < algorithm> // std::ranges::any_of
4+ #include < iomanip> // std::hex, std::setfill, std::setw
5+ #include < sstream> // std::ostringstream
56
67namespace {
78
@@ -137,7 +138,12 @@ auto TypeScript::operator()(const IRObject &entry) -> void {
137138 }
138139
139140 for (const auto &pattern_property : entry.pattern ) {
140- this ->output << " [key: `" << pattern_property.prefix << " ${string}`]: "
141+ if (!pattern_property.prefix .has_value ()) {
142+ continue ;
143+ }
144+
145+ this ->output << " [key: `" << pattern_property.prefix .value ()
146+ << " ${string}`]: "
141147 << mangle (this ->prefix , pattern_property.pointer ,
142148 pattern_property.symbol , this ->cache );
143149
@@ -146,11 +152,11 @@ auto TypeScript::operator()(const IRObject &entry) -> void {
146152 // is a sub-prefix of another (i.e. "x-data-" starts with "x-"),
147153 // intersect the types so the constraint is satisfied
148154 for (const auto &other : entry.pattern ) {
149- if (&other == &pattern_property) {
155+ if (&other == &pattern_property || !other. prefix . has_value () ) {
150156 continue ;
151157 }
152158
153- if (pattern_property.prefix .starts_with (other.prefix )) {
159+ if (pattern_property.prefix .value (). starts_with (other.prefix . value () )) {
154160 this ->output << " & "
155161 << mangle (this ->prefix , other.pointer , other.symbol ,
156162 this ->cache );
@@ -160,9 +166,14 @@ auto TypeScript::operator()(const IRObject &entry) -> void {
160166 this ->output << " ;\n " ;
161167 }
162168
169+ const auto has_non_prefix_pattern{
170+ std::ranges::any_of (entry.pattern , [](const auto &pattern_property) {
171+ return !pattern_property.prefix .has_value ();
172+ })};
173+
163174 if (allows_any_additional) {
164175 this ->output << " [key: string]: unknown | undefined;\n " ;
165- } else if (has_typed_additional) {
176+ } else if (has_typed_additional || has_non_prefix_pattern ) {
166177 // TypeScript index signatures must be a supertype of all property value
167178 // types. We use a union of all member types plus the additional properties
168179 // type plus undefined (for optional properties).
@@ -186,11 +197,14 @@ auto TypeScript::operator()(const IRObject &entry) -> void {
186197 << " |\n " ;
187198 }
188199
189- const auto &additional_type{std::get<IRType>(entry.additional )};
190- this ->output << " "
191- << mangle (this ->prefix , additional_type.pointer ,
192- additional_type.symbol , this ->cache )
193- << " |\n " ;
200+ if (has_typed_additional) {
201+ const auto &additional_type{std::get<IRType>(entry.additional )};
202+ this ->output << " "
203+ << mangle (this ->prefix , additional_type.pointer ,
204+ additional_type.symbol , this ->cache )
205+ << " |\n " ;
206+ }
207+
194208 this ->output << " undefined;\n " ;
195209 }
196210
0 commit comments