0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-02-01 12:16:11 -05:00
This commit is contained in:
Marvin Hagemeister 2025-01-09 23:50:39 +01:00
parent aed3d16ff8
commit a852c5639c
4 changed files with 330 additions and 78 deletions

View file

@ -745,7 +745,7 @@ export function compileSelector(selector) {
fn = matchNthChild(node, fn); fn = matchNthChild(node, fn);
break; break;
case PSEUDO_HAS: case PSEUDO_HAS:
// FIXME // TODO(@marvinhagemeister)
// fn = matchIs(part, fn); // fn = matchIs(part, fn);
throw new Error("TODO: :has"); throw new Error("TODO: :has");
case PSEUDO_NOT: case PSEUDO_NOT:

View file

@ -983,20 +983,8 @@ fn serialize_expr(ctx: &mut TsEsTreeBuilder, expr: &Expr) -> NodeRef {
ctx.write_ts_as_expr(&node.span, expr, type_ann) ctx.write_ts_as_expr(&node.span, expr, type_ann)
} }
Expr::TsInstantiation(_) => { Expr::TsInstantiation(_) => {
// let raw = ctx.header(AstNode::TsInstantiation, parent, &node.span); // Invalid syntax
// let expr_pos = ctx.ref_field(AstProp::Expression); unreachable!()
// let type_args_pos = ctx.ref_field(AstProp::TypeArguments);
// let pos = ctx.commit_schema(raw);
// let expr = serialize_expr(ctx, node.expr.as_ref(), pos);
// let type_arg = serialize_ts_param_inst(ctx, node.type_args.as_ref(), pos);
// ctx.write_ref(expr_pos, expr);
// ctx.write_ref(type_args_pos, type_arg);
// pos
todo!()
} }
Expr::TsSatisfies(node) => { Expr::TsSatisfies(node) => {
let expr = serialize_expr(ctx, node.expr.as_ref()); let expr = serialize_expr(ctx, node.expr.as_ref());
@ -1052,7 +1040,6 @@ fn serialize_prop_or_spread(
let mut method = false; let mut method = false;
let mut kind = "init"; let mut kind = "init";
// FIXME: optional
let (key, value) = match prop.as_ref() { let (key, value) = match prop.as_ref() {
Prop::Shorthand(ident) => { Prop::Shorthand(ident) => {
shorthand = true; shorthand = true;
@ -1095,8 +1082,8 @@ fn serialize_prop_or_spread(
body: getter_prop.body.clone(), body: getter_prop.body.clone(),
is_generator: false, is_generator: false,
is_async: false, is_async: false,
type_params: None, // FIXME type_params: None,
return_type: None, return_type: getter_prop.type_ann.clone(),
}), }),
}), }),
); );
@ -1398,21 +1385,17 @@ fn serialize_decl(ctx: &mut TsEsTreeBuilder, decl: &Decl) -> NodeRef {
ctx.write_ts_enum(&node.span, node.declare, node.is_const, id, body) ctx.write_ts_enum(&node.span, node.declare, node.is_const, id, body)
} }
Decl::TsModule(node) => { Decl::TsModule(node) => {
let ident = match node.id { let ident = match &node.id {
TsModuleName::Ident(ident) => serialize_ident(ctx, &ident), TsModuleName::Ident(ident) => serialize_ident(ctx, &ident),
TsModuleName::Str(str_lit) => { TsModuleName::Str(str_lit) => {
serialize_lit(ctx, &Lit::Str(str_lit.clone())) serialize_lit(ctx, &Lit::Str(str_lit.clone()))
} }
}; };
let body = node.body.as_ref().map(|body| match body { let body = node
TsNamespaceBody::TsModuleBlock(mod_block) => { .body
let items = mod_block.body; .as_ref()
// TODO .map(|body| serialize_ts_namespace_body(ctx, body));
ctx.write_ts_module_block(&mod_block.span, items)
}
TsNamespaceBody::TsNamespaceDecl(ts_namespace_decl) => todo!(),
});
ctx.write_ts_module_decl( ctx.write_ts_module_decl(
&node.span, &node.span,
@ -1425,6 +1408,38 @@ fn serialize_decl(ctx: &mut TsEsTreeBuilder, decl: &Decl) -> NodeRef {
} }
} }
fn serialize_ts_namespace_body(
ctx: &mut TsEsTreeBuilder,
node: &TsNamespaceBody,
) -> NodeRef {
match node {
TsNamespaceBody::TsModuleBlock(mod_block) => {
let items = mod_block
.body
.iter()
.map(|item| match item {
ModuleItem::ModuleDecl(decl) => serialize_module_decl(ctx, decl),
ModuleItem::Stmt(stmt) => serialize_stmt(ctx, stmt),
})
.collect::<Vec<_>>();
ctx.write_ts_module_block(&mod_block.span, items)
}
TsNamespaceBody::TsNamespaceDecl(node) => {
let ident = serialize_ident(ctx, &node.id);
let body = serialize_ts_namespace_body(ctx, &node.body);
ctx.write_ts_module_decl(
&node.span,
node.declare,
node.global,
ident,
Some(body),
)
}
}
}
fn serialize_ts_type_elem( fn serialize_ts_type_elem(
ctx: &mut TsEsTreeBuilder, ctx: &mut TsEsTreeBuilder,
node: &TsTypeElement, node: &TsTypeElement,
@ -1483,38 +1498,26 @@ fn serialize_ts_type_elem(
ctx.write_ts_setter_sig(&sig.span, key, param) ctx.write_ts_setter_sig(&sig.span, key, param)
} }
TsTypeElement::TsMethodSignature(_sig) => { TsTypeElement::TsMethodSignature(sig) => {
todo!() let key = serialize_expr(ctx, &sig.key);
// let raw = ctx.header(AstNode::TSMethodSignature, pos, &sig.span); let type_parms =
// let computed_pos = ctx.bool_field(AstProp::Computed); maybe_serialize_ts_type_param_decl(ctx, &sig.type_params);
// let optional_pos = ctx.bool_field(AstProp::Optional); let params = sig
// let readonly_pos = ctx.bool_field(AstProp::Readonly); .params
// // TODO: where is this coming from? .iter()
// let _static_bos = ctx.bool_field(AstProp::Static); .map(|param| serialize_ts_fn_param(ctx, param))
// let kind_pos = ctx.str_field(AstProp::Kind); .collect::<Vec<_>>();
// let key_pos = ctx.ref_field(AstProp::Key); let return_type = maybe_serialize_ts_type_ann(ctx, &sig.type_ann);
// let params_pos =
// ctx.ref_vec_field(AstProp::Params, sig.params.len());
// let return_type_pos = ctx.ref_field(AstProp::ReturnType);
// let item_pos = ctx.commit_schema(raw);
// let key = serialize_expr(ctx, sig.key.as_ref()); ctx.write_ts_method_sig(
// let params = sig &sig.span,
// .params sig.computed,
// .iter() sig.optional,
// .map(|param| serialize_ts_fn_param(ctx, param)) key,
// .collect::<Vec<_>>(); type_parms,
// let return_type = maybe_serialize_ts_type_ann(ctx, &sig.type_ann); params,
return_type,
// ctx.write_bool(computed_pos, false); )
// ctx.write_bool(optional_pos, false);
// ctx.write_bool(readonly_pos, false);
// ctx.write_str(kind_pos, "method");
// ctx.write_ref(key_pos, key);
// ctx.write_refs(params_pos, params);
// ctx.write_maybe_ref(return_type_pos, return_type);
// item_pos
} }
TsTypeElement::TsIndexSignature(sig) => serialize_ts_index_sig(ctx, sig), TsTypeElement::TsIndexSignature(sig) => serialize_ts_index_sig(ctx, sig),
} }
@ -1634,7 +1637,10 @@ fn serialize_jsx_opening_element(
) -> NodeRef { ) -> NodeRef {
let name = serialize_jsx_element_name(ctx, &node.name); let name = serialize_jsx_element_name(ctx, &node.name);
// FIXME: type args let type_args = node
.type_args
.as_ref()
.map(|arg| serialize_ts_param_inst(ctx, arg));
let attrs = node let attrs = node
.attrs .attrs
@ -1668,7 +1674,13 @@ fn serialize_jsx_opening_element(
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
ctx.write_jsx_opening_elem(&node.span, node.self_closing, name, attrs) ctx.write_jsx_opening_elem(
&node.span,
node.self_closing,
name,
attrs,
type_args,
)
} }
fn serialize_jsx_container_expr( fn serialize_jsx_container_expr(
@ -1753,8 +1765,6 @@ fn serialize_pat(ctx: &mut TsEsTreeBuilder, pat: &Pat) -> NodeRef {
ObjectPatProp::Assign(assign_pat_prop) => { ObjectPatProp::Assign(assign_pat_prop) => {
let ident = serialize_ident(ctx, &assign_pat_prop.key.id); let ident = serialize_ident(ctx, &assign_pat_prop.key.id);
// TODO(@marvinhagemeister): This seems wrong
let value = assign_pat_prop let value = assign_pat_prop
.value .value
.as_ref() .as_ref()
@ -2292,9 +2302,14 @@ fn serialize_ts_type(ctx: &mut TsEsTreeBuilder, node: &TsType) -> NodeRef {
ctx.write_ts_type_query(&node.span, expr_name, type_args) ctx.write_ts_type_query(&node.span, expr_name, type_args)
} }
TsType::TsTypeLit(_) => { TsType::TsTypeLit(node) => {
// TODO: Not sure what this is let members = node
todo!() .members
.iter()
.map(|member| serialize_ts_type_elem(ctx, member))
.collect::<Vec<_>>();
ctx.write_ts_type_lit(&node.span, members)
} }
TsType::TsArrayType(node) => { TsType::TsArrayType(node) => {
let elem = serialize_ts_type(ctx, &node.elem_type); let elem = serialize_ts_type(ctx, &node.elem_type);
@ -2318,7 +2333,10 @@ fn serialize_ts_type(ctx: &mut TsEsTreeBuilder, node: &TsType) -> NodeRef {
ctx.write_ts_tuple_type(&node.span, children) ctx.write_ts_tuple_type(&node.span, children)
} }
TsType::TsOptionalType(_) => todo!(), TsType::TsOptionalType(node) => {
let type_ann = serialize_ts_type(ctx, &node.type_ann);
ctx.write_ts_optional_type(&node.span, type_ann)
}
TsType::TsRestType(node) => { TsType::TsRestType(node) => {
let type_ann = serialize_ts_type(ctx, &node.type_ann); let type_ann = serialize_ts_type(ctx, &node.type_ann);
ctx.write_ts_rest_type(&node.span, type_ann) ctx.write_ts_rest_type(&node.span, type_ann)
@ -2355,7 +2373,10 @@ fn serialize_ts_type(ctx: &mut TsEsTreeBuilder, node: &TsType) -> NodeRef {
let param = serialize_ts_type_param(ctx, &node.type_param); let param = serialize_ts_type_param(ctx, &node.type_param);
ctx.write_ts_infer_type(&node.span, param) ctx.write_ts_infer_type(&node.span, param)
} }
TsType::TsParenthesizedType(_) => todo!(), TsType::TsParenthesizedType(node) => {
// Not materialized in TSEstree
serialize_ts_type(ctx, &node.type_ann)
}
TsType::TsTypeOperator(node) => { TsType::TsTypeOperator(node) => {
let type_ann = serialize_ts_type(ctx, &node.type_ann); let type_ann = serialize_ts_type(ctx, &node.type_ann);
@ -2374,20 +2395,18 @@ fn serialize_ts_type(ctx: &mut TsEsTreeBuilder, node: &TsType) -> NodeRef {
ctx.write_ts_indexed_access_type(&node.span, index, obj) ctx.write_ts_indexed_access_type(&node.span, index, obj)
} }
TsType::TsMappedType(node) => { TsType::TsMappedType(node) => {
// let opt_pos =
// create_true_plus_minus_field(ctx, AstProp::Optional, node.optional);
// let readonly_pos =
// create_true_plus_minus_field(ctx, AstProp::Readonly, node.readonly);
let name = maybe_serialize_ts_type(ctx, &node.name_type); let name = maybe_serialize_ts_type(ctx, &node.name_type);
let type_ann = maybe_serialize_ts_type(ctx, &node.type_ann); let type_ann = maybe_serialize_ts_type(ctx, &node.type_ann);
let type_param = serialize_ts_type_param(ctx, &node.type_param); let type_param = serialize_ts_type_param(ctx, &node.type_param);
// FIXME: true plus minus ctx.write_ts_mapped_type(
// write_true_plus_minus(ctx, opt_pos, node.optional); &node.span,
// write_true_plus_minus(ctx, readonly_pos, node.readonly); node.readonly,
node.optional,
ctx.write_ts_mapped_type(&node.span, name, type_ann, type_param) name,
type_ann,
type_param,
)
} }
TsType::TsLitType(node) => serialize_ts_lit_type(ctx, node), TsType::TsLitType(node) => serialize_ts_lit_type(ctx, node),
TsType::TsTypePredicate(node) => { TsType::TsTypePredicate(node) => {
@ -2458,7 +2477,12 @@ fn serialize_ts_entity_name(
node: &TsEntityName, node: &TsEntityName,
) -> NodeRef { ) -> NodeRef {
match &node { match &node {
TsEntityName::TsQualifiedName(_) => todo!(), TsEntityName::TsQualifiedName(node) => {
let left = serialize_ts_entity_name(ctx, &node.left);
let right = serialize_ident_name(ctx, &node.right);
ctx.write_ts_qualified_name(&node.span, left, right)
}
TsEntityName::Ident(ident) => serialize_ident(ctx, ident), TsEntityName::Ident(ident) => serialize_ident(ctx, ident),
} }
} }

View file

@ -5,6 +5,7 @@ use std::fmt::Debug;
use std::fmt::Display; use std::fmt::Display;
use deno_ast::swc::common::Span; use deno_ast::swc::common::Span;
use deno_ast::view::TruePlusMinus;
use super::buffer::AstBufSerializer; use super::buffer::AstBufSerializer;
use super::buffer::NodeRef; use super::buffer::NodeRef;
@ -149,6 +150,7 @@ pub enum AstNode {
TSTypeReference, TSTypeReference,
TSThisType, TSThisType,
TSLiteralType, TSLiteralType,
TSTypeLiteral,
TSInferType, TSInferType,
TSConditionalType, TSConditionalType,
TSUnionType, TSUnionType,
@ -174,6 +176,8 @@ pub enum AstNode {
TSEmptyBodyFunctionExpression, TSEmptyBodyFunctionExpression,
TSParameterProperty, TSParameterProperty,
TSConstructSignatureDeclaration, TSConstructSignatureDeclaration,
TSQualifiedName,
TSOptionalType,
TSAnyKeyword, TSAnyKeyword,
TSBigIntKeyword, TSBigIntKeyword,
@ -1748,12 +1752,16 @@ impl TsEsTreeBuilder {
self_closing: bool, self_closing: bool,
name: NodeRef, name: NodeRef,
attrs: Vec<NodeRef>, attrs: Vec<NodeRef>,
type_args: Option<NodeRef>,
) -> NodeRef { ) -> NodeRef {
let id = self.ctx.append_node(AstNode::JSXOpeningElement, span); let id = self.ctx.append_node(AstNode::JSXOpeningElement, span);
self.ctx.write_bool(AstProp::SelfClosing, self_closing); self.ctx.write_bool(AstProp::SelfClosing, self_closing);
self.ctx.write_ref(AstProp::Name, &id, name); self.ctx.write_ref(AstProp::Name, &id, name);
self.ctx.write_ref_vec(AstProp::Attributes, &id, attrs); self.ctx.write_ref_vec(AstProp::Attributes, &id, attrs);
self
.ctx
.write_maybe_ref(AstProp::TypeArguments, &id, type_args);
self.ctx.commit_node(id) self.ctx.commit_node(id)
} }
@ -2269,6 +2277,35 @@ impl TsEsTreeBuilder {
self.ctx.commit_node(id) self.ctx.commit_node(id)
} }
pub fn write_ts_method_sig(
&mut self,
span: &Span,
is_computed: bool,
is_optional: bool,
key: NodeRef,
type_params: Option<NodeRef>,
params: Vec<NodeRef>,
return_type: Option<NodeRef>,
) -> NodeRef {
let id = self.ctx.append_node(AstNode::TSMethodSignature, span);
self.ctx.write_bool(AstProp::Computed, is_computed);
self.ctx.write_bool(AstProp::Optional, is_optional);
self.ctx.write_bool(AstProp::Readonly, false);
self.ctx.write_bool(AstProp::Static, false);
self.ctx.write_str(AstProp::Kind, "method");
self.ctx.write_ref(AstProp::Key, &id, key);
self
.ctx
.write_maybe_ref(AstProp::TypeParameters, &id, type_params);
self.ctx.write_ref_vec(AstProp::Params, &id, params);
self
.ctx
.write_maybe_ref(AstProp::ReturnType, &id, return_type);
self.ctx.commit_node(id)
}
pub fn write_ts_interface_heritage( pub fn write_ts_interface_heritage(
&mut self, &mut self,
span: &Span, span: &Span,
@ -2417,12 +2454,16 @@ impl TsEsTreeBuilder {
pub fn write_ts_mapped_type( pub fn write_ts_mapped_type(
&mut self, &mut self,
span: &Span, span: &Span,
readonly: Option<TruePlusMinus>,
optional: Option<TruePlusMinus>,
name: Option<NodeRef>, name: Option<NodeRef>,
type_ann: Option<NodeRef>, type_ann: Option<NodeRef>,
type_param: NodeRef, type_param: NodeRef,
) -> NodeRef { ) -> NodeRef {
let id = self.ctx.append_node(AstNode::TSMappedType, span); let id = self.ctx.append_node(AstNode::TSMappedType, span);
self.write_plus_minus_true(AstProp::Readonly, readonly);
self.write_plus_minus_true(AstProp::Optional, optional);
self.ctx.write_maybe_ref(AstProp::NameType, &id, name); self.ctx.write_maybe_ref(AstProp::NameType, &id, name);
self self
.ctx .ctx
@ -2438,6 +2479,26 @@ impl TsEsTreeBuilder {
self.ctx.commit_node(id) self.ctx.commit_node(id)
} }
pub fn write_ts_type_lit(
&mut self,
span: &Span,
members: Vec<NodeRef>,
) -> NodeRef {
let id = self.ctx.append_node(AstNode::TSTypeLiteral, span);
self.ctx.write_ref_vec(AstProp::Members, &id, members);
self.ctx.commit_node(id)
}
pub fn write_ts_optional_type(
&mut self,
span: &Span,
type_ann: NodeRef,
) -> NodeRef {
let id = self.ctx.append_node(AstNode::TSOptionalType, span);
self.ctx.write_ref(AstProp::TypeAnnotation, &id, type_ann);
self.ctx.commit_node(id)
}
pub fn write_ts_type_ann( pub fn write_ts_type_ann(
&mut self, &mut self,
span: &Span, span: &Span,
@ -2608,6 +2669,20 @@ impl TsEsTreeBuilder {
self.ctx.commit_node(id) self.ctx.commit_node(id)
} }
pub fn write_ts_qualified_name(
&mut self,
span: &Span,
left: NodeRef,
right: NodeRef,
) -> NodeRef {
let id = self.ctx.append_node(AstNode::TSQualifiedName, span);
self.ctx.write_ref(AstProp::Left, &id, left);
self.ctx.write_ref(AstProp::Right, &id, right);
self.ctx.commit_node(id)
}
fn write_accessibility(&mut self, accessibility: Option<String>) { fn write_accessibility(&mut self, accessibility: Option<String>) {
if let Some(value) = accessibility { if let Some(value) = accessibility {
self.ctx.write_str(AstProp::Accessibility, &value); self.ctx.write_str(AstProp::Accessibility, &value);
@ -2615,6 +2690,19 @@ impl TsEsTreeBuilder {
self.ctx.write_undefined(AstProp::Accessibility); self.ctx.write_undefined(AstProp::Accessibility);
} }
} }
fn write_plus_minus_true(
&mut self,
prop: AstProp,
value: Option<TruePlusMinus>,
) {
match value {
Some(TruePlusMinus::Plus) => self.ctx.write_str(prop, "+"),
Some(TruePlusMinus::Minus) => self.ctx.write_str(prop, "-"),
Some(TruePlusMinus::True) => self.ctx.write_bool(prop, true),
_ => self.ctx.write_undefined(prop),
}
}
} }
#[derive(Debug)] #[derive(Debug)]

View file

@ -721,6 +721,24 @@ Deno.test("Plugin - Literal", async (t) => {
await testSnapshot(t, "/foo/g", "Literal"); await testSnapshot(t, "/foo/g", "Literal");
}); });
Deno.test("Plugin - JSXElement + JSXOpeningElement + JSXClosingElement + JSXAttr", async (t) => {
await testSnapshot(t, "<div />", "JSXElement");
await testSnapshot(t, "<div></div>", "JSXElement");
await testSnapshot(t, "<div a></div>", "JSXElement");
await testSnapshot(t, '<div a="b" />', "JSXElement");
await testSnapshot(t, "<div a={2} />", "JSXElement");
await testSnapshot(t, "<div>foo{2}</div>", "JSXElement");
await testSnapshot(t, "<a.b />", "JSXElement");
await testSnapshot(t, "<div a:b={2} />", "JSXElement");
await testSnapshot(t, "<Foo />", "JSXElement");
await testSnapshot(t, "<Foo<T> />", "JSXElement");
});
Deno.test("Plugin - JSXFragment + JSXOpeningFragment + JSXClosingFragment", async (t) => {
await testSnapshot(t, "<></>", "JSXFragment");
await testSnapshot(t, "<>foo{2}</>", "JSXFragment");
});
Deno.test("Plugin - TSAsExpression", async (t) => { Deno.test("Plugin - TSAsExpression", async (t) => {
await testSnapshot(t, "a as any", "TSAsExpression"); await testSnapshot(t, "a as any", "TSAsExpression");
await testSnapshot(t, '"foo" as const', "TSAsExpression"); await testSnapshot(t, '"foo" as const', "TSAsExpression");
@ -755,6 +773,12 @@ Deno.test("Plugin - TSInterface", async (t) => {
await testSnapshot(t, "interface A { a: new <T>(a: T) => T }", "TSInterface"); await testSnapshot(t, "interface A { a: new <T>(a: T) => T }", "TSInterface");
await testSnapshot(t, "interface A { get a(): string }", "TSInterface"); await testSnapshot(t, "interface A { get a(): string }", "TSInterface");
await testSnapshot(t, "interface A { set a(v: string) }", "TSInterface"); await testSnapshot(t, "interface A { set a(v: string) }", "TSInterface");
await testSnapshot(
t,
"interface A { a<T>(arg?: any, ...args: any[]): any",
"TSInterface",
);
}); });
Deno.test("Plugin - TSSatisfiesExpression", async (t) => { Deno.test("Plugin - TSSatisfiesExpression", async (t) => {
@ -787,3 +811,119 @@ Deno.test("Plugin - TSModuleDeclaration", async (t) => {
"TSModuleDeclaration", "TSModuleDeclaration",
); );
}); });
Deno.test("Plugin - TSModuleDeclaration + TSModuleBlock", async (t) => {
await testSnapshot(t, "module A {}", "TSModuleDeclaration");
await testSnapshot(
t,
"namespace A { namespace B {} }",
"TSModuleDeclaration",
);
});
Deno.test("Plugin - TSQualifiedName", async (t) => {
await testSnapshot(t, "type A = a.b;", "TSQualifiedName");
await testSnapshot(
t,
"declare module A { export function A(): void }",
"TSQualifiedName",
);
});
Deno.test("Plugin - TSTypeLiteral", async (t) => {
await testSnapshot(t, "type A = { a: 1 };", "TSTypeLiteral");
});
Deno.test("Plugin - TSOptionalType", async (t) => {
await testSnapshot(t, "type A = [number?]", "TSOptionalType");
});
Deno.test("Plugin - TSRestType", async (t) => {
await testSnapshot(t, "type A = [...number[]]", "TSRestType");
});
Deno.test("Plugin - TSConditionalType", async (t) => {
await testSnapshot(
t,
"type A = B extends C ? number : string;",
"TSConditionalType",
);
});
Deno.test("Plugin - TSInferType", async (t) => {
await testSnapshot(
t,
"type A<T> = T extends Array<infer Item> ? Item : T;",
"TSInferType",
);
});
Deno.test("Plugin - TSTypeOperator", async (t) => {
await testSnapshot(t, "type A = keyof B", "TSTypeOperator");
await testSnapshot(t, "declare const sym1: unique symbol;", "TSTypeOperator");
await testSnapshot(t, "type A = readonly []", "TSTypeOperator");
});
Deno.test("Plugin - TSMappedType", async (t) => {
await testSnapshot(
t,
"type A<T> = { [P in keyof T]: boolean; };",
"TSMappedType",
);
await testSnapshot(
t,
"type A<T> = { readonly [P in keyof T]: []; };",
"TSMappedType",
);
await testSnapshot(
t,
"type A<T> = { -readonly [P in keyof T]: []; };",
"TSMappedType",
);
await testSnapshot(
t,
"type A<T> = { +readonly [P in keyof T]: []; };",
"TSMappedType",
);
await testSnapshot(
t,
"type A<T> = { [P in keyof T]?: boolean; };",
"TSMappedType",
);
await testSnapshot(
t,
"type A<T> = { [P in keyof T]-?: boolean; };",
"TSMappedType",
);
await testSnapshot(
t,
"type A<T> = { [P in keyof T]+?: boolean; };",
"TSMappedType",
);
});
Deno.test("Plugin - TSLiteralType", async (t) => {
await testSnapshot(t, "type A = true", "TSLiteralType");
await testSnapshot(t, "type A = false", "TSLiteralType");
await testSnapshot(t, "type A = 1", "TSLiteralType");
await testSnapshot(t, "type A = 'foo''", "TSLiteralType");
});
Deno.test("Plugin - TSTemplateLiteralType", async (t) => {
await testSnapshot(
t,
"type A<B extends string> = `a ${B}`",
"TSTemplateLiteralType",
);
});
Deno.test("Plugin - TSTupleType + TSArrayType", async (t) => {
await testSnapshot(t, "type A = [number]", "TSTupleType");
await testSnapshot(t, "type A = [x: number]", "TSTupleType");
await testSnapshot(t, "type A = [x: number]", "TSTupleType");
await testSnapshot(t, "type A = [...x: number[]]", "TSTupleType");
});
Deno.test("Plugin - TSTypeQuery", async (t) => {
await testSnapshot(t, "type A = typeof B", "TSTupleType");
});