mirror of
https://github.com/danbulant/oxc
synced 2026-05-25 04:42:10 +00:00
feat(transformer/typescript): correct elide imports/exports statements (#2995)
remove ts annotations one benefit: `IdentifierReference` only used on js
code
The `TypescriptReferenceCollector` implementation is inspired by
5f75019683/crates/swc_ecma_transforms_typescript/src/strip_import_export.rs (L9-L99)
This seems simpler to implement than using scope
This commit is contained in:
parent
ac37d55600
commit
6a53fa367b
5 changed files with 174 additions and 108 deletions
|
|
@ -143,8 +143,6 @@ impl<'a> VisitMut<'a> for Transformer<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_import_declaration(&mut self, decl: &mut ImportDeclaration<'a>) {
|
fn visit_import_declaration(&mut self, decl: &mut ImportDeclaration<'a>) {
|
||||||
self.x0_typescript.transform_import_declaration(decl);
|
|
||||||
|
|
||||||
walk_mut::walk_import_declaration_mut(self, decl);
|
walk_mut::walk_import_declaration_mut(self, decl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -198,4 +196,14 @@ impl<'a> VisitMut<'a> for Transformer<'a> {
|
||||||
|
|
||||||
walk_mut::walk_variable_declarator_mut(self, declarator);
|
walk_mut::walk_variable_declarator_mut(self, declarator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_identifier_reference(&mut self, ident: &mut IdentifierReference<'a>) {
|
||||||
|
self.x0_typescript.transform_identifier_reference(ident);
|
||||||
|
walk_mut::walk_identifier_reference_mut(self, ident);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_statement(&mut self, stmt: &mut Statement<'a>) {
|
||||||
|
self.x0_typescript.transform_statement(stmt);
|
||||||
|
walk_mut::walk_statement_mut(self, stmt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,25 +11,17 @@ use oxc_span::{Atom, SPAN};
|
||||||
use oxc_syntax::operator::AssignmentOperator;
|
use oxc_syntax::operator::AssignmentOperator;
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
|
|
||||||
|
use super::collector::TypeScriptReferenceCollector;
|
||||||
|
|
||||||
pub struct TypeScriptAnnotations<'a> {
|
pub struct TypeScriptAnnotations<'a> {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
options: Rc<TypeScriptOptions>,
|
options: Rc<TypeScriptOptions>,
|
||||||
ctx: Ctx<'a>,
|
ctx: Ctx<'a>,
|
||||||
|
|
||||||
global_types: FxHashSet<String>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TypeScriptAnnotations<'a> {
|
impl<'a> TypeScriptAnnotations<'a> {
|
||||||
pub fn new(options: &Rc<TypeScriptOptions>, ctx: &Ctx<'a>) -> Self {
|
pub fn new(options: &Rc<TypeScriptOptions>, ctx: &Ctx<'a>) -> Self {
|
||||||
Self {
|
Self { options: Rc::clone(options), ctx: Rc::clone(ctx) }
|
||||||
options: Rc::clone(options),
|
|
||||||
ctx: Rc::clone(ctx),
|
|
||||||
global_types: FxHashSet::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_global_type(&self) -> bool {
|
|
||||||
self.global_types.contains("TODO")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert `export = expr` into `module.exports = expr`
|
// Convert `export = expr` into `module.exports = expr`
|
||||||
|
|
@ -73,57 +65,113 @@ impl<'a> TypeScriptAnnotations<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove type only imports/exports
|
// Remove type only imports/exports
|
||||||
pub fn transform_program_on_exit(&self, program: &mut Program<'a>) {
|
pub fn transform_program_on_exit(
|
||||||
|
&self,
|
||||||
|
program: &mut Program<'a>,
|
||||||
|
references: &TypeScriptReferenceCollector,
|
||||||
|
) {
|
||||||
|
let mut import_type_names = FxHashSet::default();
|
||||||
let mut module_count = 0;
|
let mut module_count = 0;
|
||||||
|
let mut removed_count = 0;
|
||||||
|
|
||||||
let body =
|
program.body.retain_mut(|stmt| {
|
||||||
self.ctx.ast.move_statement_vec(&mut program.body).into_iter().filter_map(|stmt| {
|
let Statement::ModuleDeclaration(module_decl) = stmt else {
|
||||||
// If an import/export declaration, remove all that are type-only
|
return true;
|
||||||
if let Statement::ModuleDeclaration(decl) = &stmt {
|
};
|
||||||
let keep = match &**decl {
|
|
||||||
ModuleDeclaration::ImportDeclaration(inner) => !inner.import_kind.is_type(),
|
|
||||||
ModuleDeclaration::ExportAllDeclaration(inner) => {
|
|
||||||
!inner.is_typescript_syntax()
|
|
||||||
}
|
|
||||||
ModuleDeclaration::ExportNamedDeclaration(inner) => {
|
|
||||||
!(inner.is_typescript_syntax()
|
|
||||||
|| inner.specifiers.is_empty()
|
|
||||||
|| inner.specifiers.iter().all(|spec| spec.export_kind.is_type())
|
|
||||||
|| self.is_global_type())
|
|
||||||
}
|
|
||||||
ModuleDeclaration::ExportDefaultDeclaration(inner) => {
|
|
||||||
!inner.is_typescript_syntax()
|
|
||||||
}
|
|
||||||
ModuleDeclaration::TSNamespaceExportDeclaration(_) => false,
|
|
||||||
|
|
||||||
// Replace with `module.exports = expr`
|
let need_delete = match &mut **module_decl {
|
||||||
ModuleDeclaration::TSExportAssignment(exp) => {
|
ModuleDeclaration::ExportNamedDeclaration(decl) => {
|
||||||
return Some(self.create_module_exports(exp));
|
decl.specifiers.retain(|specifier| {
|
||||||
}
|
!(specifier.export_kind.is_type()
|
||||||
};
|
|| import_type_names.contains(specifier.exported.name()))
|
||||||
|
});
|
||||||
|
|
||||||
if keep {
|
decl.export_kind.is_type()
|
||||||
module_count += 1;
|
|| ((decl.declaration.is_none()
|
||||||
} else {
|
|| decl.declaration.as_ref().is_some_and(|d| {
|
||||||
return None;
|
d.modifiers().is_some_and(|modifiers| {
|
||||||
}
|
modifiers.contains(ModifierKind::Declare)
|
||||||
|
}) || matches!(
|
||||||
|
d,
|
||||||
|
Declaration::TSInterfaceDeclaration(_)
|
||||||
|
| Declaration::TSTypeAliasDeclaration(_)
|
||||||
|
)
|
||||||
|
}))
|
||||||
|
&& decl.specifiers.is_empty())
|
||||||
}
|
}
|
||||||
|
ModuleDeclaration::ImportDeclaration(decl) => {
|
||||||
|
let is_type = decl.import_kind.is_type();
|
||||||
|
|
||||||
Some(stmt)
|
let is_specifiers_empty =
|
||||||
});
|
decl.specifiers.as_ref().is_some_and(|s| s.is_empty());
|
||||||
|
|
||||||
program.body = self.ctx.ast.new_vec_from_iter(body);
|
if let Some(specifiers) = &mut decl.specifiers {
|
||||||
|
specifiers.retain(|specifier| match specifier {
|
||||||
|
ImportDeclarationSpecifier::ImportSpecifier(s) => {
|
||||||
|
if is_type || s.import_kind.is_type() {
|
||||||
|
import_type_names.insert(s.local.name.clone());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.options.only_remove_type_imports {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
references.has_reference(&s.local.name)
|
||||||
|
}
|
||||||
|
ImportDeclarationSpecifier::ImportDefaultSpecifier(s) => {
|
||||||
|
if is_type {
|
||||||
|
import_type_names.insert(s.local.name.clone());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.options.only_remove_type_imports {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
references.has_reference(&s.local.name)
|
||||||
|
}
|
||||||
|
ImportDeclarationSpecifier::ImportNamespaceSpecifier(s) => {
|
||||||
|
if is_type {
|
||||||
|
import_type_names.insert(s.local.name.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.options.only_remove_type_imports {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
references.has_reference(&s.local.name)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
decl.import_kind.is_type()
|
||||||
|
|| (!self.options.only_remove_type_imports
|
||||||
|
&& !is_specifiers_empty
|
||||||
|
&& decl
|
||||||
|
.specifiers
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|specifiers| specifiers.is_empty()))
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
if need_delete {
|
||||||
|
removed_count += 1;
|
||||||
|
} else {
|
||||||
|
module_count += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
!need_delete
|
||||||
|
});
|
||||||
|
|
||||||
// Determine if we still have import/export statements, otherwise we
|
// Determine if we still have import/export statements, otherwise we
|
||||||
// need to inject an empty statement (`export {}`) so that the file is
|
// need to inject an empty statement (`export {}`) so that the file is
|
||||||
// still considered a module
|
// still considered a module
|
||||||
if module_count == 0 && self.ctx.semantic.source_type().is_module() {
|
if module_count == 0 && removed_count > 0 {
|
||||||
// FIXME
|
let export_decl = ModuleDeclaration::ExportNamedDeclaration(
|
||||||
// program.body.push(self.ctx.ast.module_declaration(
|
self.ctx.ast.plain_export_named_declaration(SPAN, self.ctx.ast.new_vec(), None),
|
||||||
// ModuleDeclaration::ExportNamedDeclaration(
|
);
|
||||||
// self.ctx.ast.plain_export_named_declaration(SPAN, self.ctx.ast.new_vec(), None),
|
program.body.push(self.ctx.ast.module_declaration(export_decl));
|
||||||
// ),
|
|
||||||
// ));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -172,11 +220,6 @@ impl<'a> TypeScriptAnnotations<'a> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_export_named_declaration(&mut self, decl: &mut ExportNamedDeclaration<'a>) {
|
|
||||||
// Remove type only specifiers
|
|
||||||
decl.specifiers.retain(|spec| !spec.export_kind.is_type());
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn transform_expression(&mut self, expr: &mut Expression<'a>) {
|
pub fn transform_expression(&mut self, expr: &mut Expression<'a>) {
|
||||||
*expr = self.ctx.ast.copy(expr.get_inner_expression());
|
*expr = self.ctx.ast.copy(expr.get_inner_expression());
|
||||||
}
|
}
|
||||||
|
|
@ -196,16 +239,6 @@ impl<'a> TypeScriptAnnotations<'a> {
|
||||||
func.modifiers.remove_type_modifiers();
|
func.modifiers.remove_type_modifiers();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_import_declaration(&mut self, decl: &mut ImportDeclaration<'a>) {
|
|
||||||
// Remove type only specifiers
|
|
||||||
if let Some(specifiers) = &mut decl.specifiers {
|
|
||||||
specifiers.retain(|spec| match spec {
|
|
||||||
ImportDeclarationSpecifier::ImportSpecifier(inner) => !inner.import_kind.is_type(),
|
|
||||||
_ => true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn transform_jsx_opening_element(&mut self, elem: &mut JSXOpeningElement<'a>) {
|
pub fn transform_jsx_opening_element(&mut self, elem: &mut JSXOpeningElement<'a>) {
|
||||||
elem.type_parameters = None;
|
elem.type_parameters = None;
|
||||||
}
|
}
|
||||||
|
|
@ -284,4 +317,12 @@ impl<'a> TypeScriptAnnotations<'a> {
|
||||||
) {
|
) {
|
||||||
expr.type_parameters = None;
|
expr.type_parameters = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn transform_statement(&mut self, decl: &mut Statement<'a>) {
|
||||||
|
if let Statement::ModuleDeclaration(module_decl) = decl {
|
||||||
|
if let ModuleDeclaration::TSExportAssignment(exp) = &mut **module_decl {
|
||||||
|
*decl = self.create_module_exports(exp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
36
crates/oxc_transformer/src/typescript/collector.rs
Normal file
36
crates/oxc_transformer/src/typescript/collector.rs
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
use oxc_ast::ast::{ExportNamedDeclaration, IdentifierReference};
|
||||||
|
use oxc_span::Atom;
|
||||||
|
use rustc_hash::FxHashSet;
|
||||||
|
|
||||||
|
/// Collects identifier references
|
||||||
|
/// Indicates whether the BindingIdentifier is referenced or used in the ExportNamedDeclaration
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct TypeScriptReferenceCollector<'a> {
|
||||||
|
names: FxHashSet<Atom<'a>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> TypeScriptReferenceCollector<'a> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self { names: FxHashSet::default() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn has_reference(&self, name: &Atom) -> bool {
|
||||||
|
self.names.contains(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn visit_identifier_reference(&mut self, ident: &IdentifierReference<'a>) {
|
||||||
|
self.names.insert(ident.name.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn visit_transform_export_named_declaration(&mut self, decl: &ExportNamedDeclaration<'a>) {
|
||||||
|
if decl.export_kind.is_type() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for specifier in &decl.specifiers {
|
||||||
|
if specifier.export_kind.is_value() {
|
||||||
|
self.names.insert(specifier.local.name().clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
mod annotations;
|
mod annotations;
|
||||||
|
mod collector;
|
||||||
mod namespace;
|
mod namespace;
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
@ -10,11 +11,15 @@ use oxc_ast::ast::*;
|
||||||
|
|
||||||
use crate::context::Ctx;
|
use crate::context::Ctx;
|
||||||
|
|
||||||
use self::annotations::TypeScriptAnnotations;
|
use self::{annotations::TypeScriptAnnotations, collector::TypeScriptReferenceCollector};
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Deserialize)]
|
#[derive(Debug, Default, Clone, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct TypeScriptOptions;
|
pub struct TypeScriptOptions {
|
||||||
|
/// When set to true, the transform will only remove type-only imports (introduced in TypeScript 3.8).
|
||||||
|
/// This should only be used if you are using TypeScript >= 3.8.
|
||||||
|
only_remove_type_imports: bool,
|
||||||
|
}
|
||||||
|
|
||||||
/// [Preset TypeScript](https://babeljs.io/docs/babel-preset-typescript)
|
/// [Preset TypeScript](https://babeljs.io/docs/babel-preset-typescript)
|
||||||
///
|
///
|
||||||
|
|
@ -43,6 +48,7 @@ pub struct TypeScript<'a> {
|
||||||
ctx: Ctx<'a>,
|
ctx: Ctx<'a>,
|
||||||
|
|
||||||
annotations: TypeScriptAnnotations<'a>,
|
annotations: TypeScriptAnnotations<'a>,
|
||||||
|
reference_collector: TypeScriptReferenceCollector<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TypeScript<'a> {
|
impl<'a> TypeScript<'a> {
|
||||||
|
|
@ -51,6 +57,7 @@ impl<'a> TypeScript<'a> {
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
annotations: TypeScriptAnnotations::new(&options, ctx),
|
annotations: TypeScriptAnnotations::new(&options, ctx),
|
||||||
|
reference_collector: TypeScriptReferenceCollector::new(),
|
||||||
options,
|
options,
|
||||||
ctx: Rc::clone(ctx),
|
ctx: Rc::clone(ctx),
|
||||||
}
|
}
|
||||||
|
|
@ -60,7 +67,7 @@ impl<'a> TypeScript<'a> {
|
||||||
// Transforms
|
// Transforms
|
||||||
impl<'a> TypeScript<'a> {
|
impl<'a> TypeScript<'a> {
|
||||||
pub fn transform_program_on_exit(&self, program: &mut Program<'a>) {
|
pub fn transform_program_on_exit(&self, program: &mut Program<'a>) {
|
||||||
self.annotations.transform_program_on_exit(program);
|
self.annotations.transform_program_on_exit(program, &self.reference_collector);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_arrow_expression(&mut self, expr: &mut ArrowFunctionExpression<'a>) {
|
pub fn transform_arrow_expression(&mut self, expr: &mut ArrowFunctionExpression<'a>) {
|
||||||
|
|
@ -84,7 +91,7 @@ impl<'a> TypeScript<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_export_named_declaration(&mut self, decl: &mut ExportNamedDeclaration<'a>) {
|
pub fn transform_export_named_declaration(&mut self, decl: &mut ExportNamedDeclaration<'a>) {
|
||||||
self.annotations.transform_export_named_declaration(decl);
|
self.reference_collector.visit_transform_export_named_declaration(decl);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_expression(&mut self, expr: &mut Expression<'a>) {
|
pub fn transform_expression(&mut self, expr: &mut Expression<'a>) {
|
||||||
|
|
@ -103,10 +110,6 @@ impl<'a> TypeScript<'a> {
|
||||||
self.annotations.transform_function(func, flags);
|
self.annotations.transform_function(func, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform_import_declaration(&mut self, decl: &mut ImportDeclaration<'a>) {
|
|
||||||
self.annotations.transform_import_declaration(decl);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn transform_jsx_opening_element(&mut self, elem: &mut JSXOpeningElement<'a>) {
|
pub fn transform_jsx_opening_element(&mut self, elem: &mut JSXOpeningElement<'a>) {
|
||||||
self.annotations.transform_jsx_opening_element(elem);
|
self.annotations.transform_jsx_opening_element(elem);
|
||||||
}
|
}
|
||||||
|
|
@ -137,4 +140,12 @@ impl<'a> TypeScript<'a> {
|
||||||
) {
|
) {
|
||||||
self.annotations.transform_tagged_template_expression(expr);
|
self.annotations.transform_tagged_template_expression(expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn transform_identifier_reference(&mut self, ident: &mut IdentifierReference<'a>) {
|
||||||
|
self.reference_collector.visit_identifier_reference(ident);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn transform_statement(&mut self, stmt: &mut Statement<'a>) {
|
||||||
|
self.annotations.transform_statement(stmt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
Passed: 93/227
|
Passed: 123/227
|
||||||
|
|
||||||
# All Passed:
|
# All Passed:
|
||||||
* babel-plugin-transform-react-jsx-source
|
* babel-plugin-transform-react-jsx-source
|
||||||
|
|
@ -24,7 +24,7 @@ Passed: 93/227
|
||||||
* opts/optimizeConstEnums/input.ts
|
* opts/optimizeConstEnums/input.ts
|
||||||
* opts/rewriteImportExtensions/input.ts
|
* opts/rewriteImportExtensions/input.ts
|
||||||
|
|
||||||
# babel-plugin-transform-typescript (49/147)
|
# babel-plugin-transform-typescript (79/147)
|
||||||
* class/abstract-allowDeclareFields-false/input.ts
|
* class/abstract-allowDeclareFields-false/input.ts
|
||||||
* class/abstract-allowDeclareFields-true/input.ts
|
* class/abstract-allowDeclareFields-true/input.ts
|
||||||
* class/abstract-class-decorated/input.ts
|
* class/abstract-class-decorated/input.ts
|
||||||
|
|
@ -40,48 +40,18 @@ Passed: 93/227
|
||||||
* class/private-method-override-transform-private/input.ts
|
* class/private-method-override-transform-private/input.ts
|
||||||
* class/transform-properties-declare-wrong-order/input.ts
|
* class/transform-properties-declare-wrong-order/input.ts
|
||||||
* declarations/erased/input.ts
|
* declarations/erased/input.ts
|
||||||
* declarations/export-declare-enum/input.ts
|
|
||||||
* declarations/nested-namespace/input.mjs
|
* declarations/nested-namespace/input.mjs
|
||||||
* exports/declare-namespace/input.ts
|
|
||||||
* exports/declare-shadowed/input.ts
|
* exports/declare-shadowed/input.ts
|
||||||
* exports/declared-types/input.ts
|
* exports/declared-types/input.ts
|
||||||
* exports/export-const-enums/input.ts
|
* exports/export-const-enums/input.ts
|
||||||
* exports/export-type/input.ts
|
|
||||||
* exports/export-type-from/input.ts
|
|
||||||
* exports/export-type-star-from/input.ts
|
* exports/export-type-star-from/input.ts
|
||||||
* exports/export=/input.ts
|
* exports/export=/input.ts
|
||||||
* exports/imported-types/input.ts
|
|
||||||
* exports/imported-types-only-remove-type-imports/input.ts
|
|
||||||
* exports/issue-9916-3/input.ts
|
|
||||||
* exports/simple/input.ts
|
|
||||||
* exports/type-only-export-specifier-1/input.ts
|
|
||||||
* exports/type-only-export-specifier-2/input.ts
|
|
||||||
* function/overloads-exports/input.mjs
|
* function/overloads-exports/input.mjs
|
||||||
* imports/elide-preact/input.ts
|
|
||||||
* imports/elide-react/input.ts
|
|
||||||
* imports/elide-type-referenced-in-imports-equal-no/input.ts
|
* imports/elide-type-referenced-in-imports-equal-no/input.ts
|
||||||
* imports/elide-typeof/input.ts
|
|
||||||
* imports/elision/input.ts
|
|
||||||
* imports/elision-export-type/input.ts
|
|
||||||
* imports/elision-locations/input.ts
|
|
||||||
* imports/elision-qualifiedname/input.ts
|
|
||||||
* imports/elision-rename/input.ts
|
|
||||||
* imports/enum-id/input.ts
|
* imports/enum-id/input.ts
|
||||||
* imports/enum-value/input.ts
|
* imports/enum-value/input.ts
|
||||||
* imports/import-named-type/input.ts
|
|
||||||
* imports/import-named-type-default-and-named/input.ts
|
|
||||||
* imports/import-removed-exceptions/input.ts
|
|
||||||
* imports/import-type/input.ts
|
|
||||||
* imports/import-type-func-with-duplicate-name/input.ts
|
|
||||||
* imports/import-type-not-removed/input.ts
|
|
||||||
* imports/import=-module/input.ts
|
* imports/import=-module/input.ts
|
||||||
* imports/only-remove-type-imports/input.ts
|
|
||||||
* imports/property-signature/input.ts
|
|
||||||
* imports/type-only-export-specifier-1/input.ts
|
|
||||||
* imports/type-only-export-specifier-2/input.ts
|
* imports/type-only-export-specifier-2/input.ts
|
||||||
* imports/type-only-import-specifier-2/input.ts
|
|
||||||
* imports/type-only-import-specifier-3/input.ts
|
|
||||||
* imports/type-only-import-specifier-4/input.ts
|
|
||||||
* namespace/alias/input.ts
|
* namespace/alias/input.ts
|
||||||
* namespace/ambient-module-nested/input.ts
|
* namespace/ambient-module-nested/input.ts
|
||||||
* namespace/ambient-module-nested-exported/input.ts
|
* namespace/ambient-module-nested-exported/input.ts
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue