Skip to content

Commit 12612bb

Browse files
committed
fix(typescript): parse contextual keyword: 'interface I { [type: K]: V; }'
1 parent f5b2757 commit 12612bb

File tree

3 files changed

+23
-2
lines changed

3 files changed

+23
-2
lines changed

docs/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ Semantic Versioning.
1313
* TypeScript support (still experimental):
1414
* Assigning to a variable with the same name as an `import`ed type no longer
1515
falsely reports [E0185][] ("assignment to imported variable").
16+
* Interface index signature variables can now be named contextual keywords
17+
such as `type`.
1618

1719
## 2.19.0 (2023-12-30)
1820

src/quick-lint-js/fe/parse-class.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -717,8 +717,9 @@ void Parser::parse_and_visit_class_or_interface_member(
717717
// [key: KeyType]: ValueType; // TypeScript only
718718
bool try_parse_typescript_index_signature(const Char8 *left_square_begin) {
719719
Lexer_Transaction transaction = p->lexer_.begin_transaction();
720-
// TODO(strager): Allow certain contextual keywords like 'let'?
721-
if (p->peek().type == Token_Type::identifier) {
720+
switch (p->peek().type) {
721+
QLJS_CASE_CONTEXTUAL_KEYWORD:
722+
case Token_Type::identifier: {
722723
Identifier key_variable = p->peek().identifier_name();
723724
p->skip();
724725
if (p->peek().type == Token_Type::colon) {
@@ -793,6 +794,11 @@ void Parser::parse_and_visit_class_or_interface_member(
793794
v.visit_exit_index_signature_scope();
794795
return true;
795796
}
797+
break;
798+
}
799+
800+
default:
801+
break;
796802
}
797803
p->lexer_.roll_back_transaction(std::move(transaction));
798804
return false;

test/test-parse-typescript-interface.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,19 @@ TEST_F(Test_Parse_TypeScript_Interface, interface_with_index_signature) {
679679
}
680680
}
681681

682+
TEST_F(Test_Parse_TypeScript_Interface,
683+
index_signature_variable_can_be_named_contextual_keyword) {
684+
for (String8_View keyword : contextual_keywords) {
685+
Spy_Visitor p =
686+
test_parse_and_visit_statement(concat(u8"interface I { ["_sv, keyword,
687+
u8": KeyType]: ValueType; }"_sv),
688+
no_diags, typescript_options);
689+
EXPECT_THAT(p.variable_declarations,
690+
ElementsAreArray({interface_decl(u8"I"_sv),
691+
index_signature_param_decl(keyword)}));
692+
}
693+
}
694+
682695
TEST_F(Test_Parse_TypeScript_Interface, index_signature_requires_type) {
683696
{
684697
Spy_Visitor p = test_parse_and_visit_statement(

0 commit comments

Comments
 (0)