Skip to content

Commit 350acd4

Browse files
committed
feat: #72 - TS 4.1 - Implement template literal types.
1 parent 85229ec commit 350acd4

File tree

2 files changed

+37
-15
lines changed

2 files changed

+37
-15
lines changed

src/parsing/parser.rs

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ fn parse_node_with_inner_parse<'a>(node: Node<'a>, context: &mut Context<'a>, in
270270
Node::TsParenthesizedType(node) => parse_parenthesized_type(node, context),
271271
Node::TsRestType(node) => parse_rest_type(node, context),
272272
Node::TsThisType(_) => "this".into(),
273+
Node::TsTplLitType(node) => parse_tpl_lit_type(node, context),
273274
Node::TsTupleType(node) => parse_tuple_type(node, context),
274275
Node::TsTupleElement(node) => parse_tuple_element(node, context),
275276
Node::TsTypeAnn(node) => parse_type_ann(node, context),
@@ -2062,19 +2063,27 @@ fn parse_tagged_tpl<'a>(node: &'a TaggedTpl, context: &mut Context<'a>) -> Print
20622063
if use_space { " ".into() } else { PrintItems::new() }
20632064
));
20642065

2065-
items.push_condition(conditions::indent_if_start_of_line(parse_template_literal(&node.quasis, &node.exprs.iter().map(|x| &**x).collect(), context)));
2066+
items.push_condition(conditions::indent_if_start_of_line(parse_template_literal(
2067+
node.quasis.iter().map(|n| n.into()).collect(),
2068+
node.exprs.iter().map(|x| (&**x).into()).collect(),
2069+
context,
2070+
)));
20662071
items
20672072
}
20682073

20692074
fn parse_tpl<'a>(node: &'a Tpl, context: &mut Context<'a>) -> PrintItems {
2070-
parse_template_literal(&node.quasis, &node.exprs.iter().map(|x| &**x).collect(), context)
2075+
parse_template_literal(
2076+
node.quasis.iter().map(|n| n.into()).collect(),
2077+
node.exprs.iter().map(|x| (&**x).into()).collect(),
2078+
context,
2079+
)
20712080
}
20722081

20732082
fn parse_tpl_element<'a>(node: &'a TplElement, context: &mut Context<'a>) -> PrintItems {
20742083
parse_raw_string(node.text(context).into())
20752084
}
20762085

2077-
fn parse_template_literal<'a>(quasis: &'a Vec<TplElement>, exprs: &Vec<&'a Expr>, context: &mut Context<'a>) -> PrintItems {
2086+
fn parse_template_literal<'a>(quasis: Vec<Node<'a>>, exprs: Vec<Node<'a>>, context: &mut Context<'a>) -> PrintItems {
20782087
let mut items = PrintItems::new();
20792088
items.push_str("`");
20802089
items.push_signal(Signal::StartIgnoringIndent);
@@ -2104,16 +2113,18 @@ fn parse_template_literal<'a>(quasis: &'a Vec<TplElement>, exprs: &Vec<&'a Expr>
21042113
items.push_signal(Signal::FinishIgnoringIndent);
21052114
return items;
21062115

2107-
fn get_nodes<'a>(quasis: &'a Vec<TplElement>, exprs: &Vec<&'a Expr>) -> Vec<Node<'a>> {
2108-
let quasis = quasis;
2109-
let exprs = exprs;
2116+
fn get_nodes<'a>(quasis: Vec<Node<'a>>, exprs: Vec<Node<'a>>) -> Vec<Node<'a>> {
2117+
let mut quasis = quasis;
2118+
let mut exprs = exprs;
21102119
let mut nodes = Vec::new();
2111-
let mut quasis_index = 0;
2112-
let mut exprs_index = 0;
21132120

2114-
while quasis_index < quasis.len() || exprs_index < exprs.len() {
2115-
let current_quasis = quasis.get(quasis_index);
2116-
let current_expr = exprs.get(exprs_index);
2121+
// reverse the vectors and iterate from the back
2122+
quasis.reverse();
2123+
exprs.reverse();
2124+
2125+
while !quasis.is_empty() || !exprs.is_empty() {
2126+
let current_quasis = quasis.last();
2127+
let current_expr = exprs.last();
21172128

21182129
let is_quasis = if let Some(current_quasis) = current_quasis {
21192130
if let Some(current_expr) = current_expr {
@@ -2130,11 +2141,9 @@ fn parse_template_literal<'a>(quasis: &'a Vec<TplElement>, exprs: &Vec<&'a Expr>
21302141
};
21312142

21322143
if is_quasis {
2133-
nodes.push((&quasis[quasis_index]).into());
2134-
quasis_index += 1;
2144+
nodes.push(quasis.pop().unwrap());
21352145
} else {
2136-
nodes.push(exprs[exprs_index].into());
2137-
exprs_index += 1;
2146+
nodes.push(exprs.pop().unwrap());
21382147
}
21392148
}
21402149

@@ -4124,6 +4133,14 @@ fn parse_rest_type<'a>(node: &'a TsRestType, context: &mut Context<'a>) -> Print
41244133
return items;
41254134
}
41264135

4136+
fn parse_tpl_lit_type<'a>(node: &'a TsTplLitType, context: &mut Context<'a>) -> PrintItems {
4137+
parse_template_literal(
4138+
node.quasis.iter().map(|x| x.into()).collect(),
4139+
node.types.iter().map(|x| (&**x).into()).collect(),
4140+
context,
4141+
)
4142+
}
4143+
41274144
fn parse_tuple_type<'a>(node: &'a TsTupleType, context: &mut Context<'a>) -> PrintItems {
41284145
parse_array_like_nodes(ParseArrayLikeNodesOptions {
41294146
parent_span_data: node.span,
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
== should format a template literal type ==
2+
type Test<T> = `${string & keyof T}Changed`;
3+
4+
[expect]
5+
type Test<T> = `${string & keyof T}Changed`;

0 commit comments

Comments
 (0)