feat(codegen): improve codegen formatting (#3735)

This commit is contained in:
Boshen 2024-06-18 11:10:36 +00:00
parent 4d462636cb
commit 5a99d30eba
6 changed files with 4789 additions and 4744 deletions

View file

@ -193,45 +193,46 @@ fn print_if<const MINIFY: bool>(
p.print(b'(');
p.print_expression(&if_stmt.test);
p.print(b')');
p.print_soft_space();
match &if_stmt.consequent {
Statement::BlockStatement(block) => {
p.print_soft_space();
p.print_block_statement(block, ctx);
if if_stmt.alternate.is_some() {
p.print_soft_space();
} else {
p.print_soft_newline();
}
}
stmt if wrap_to_avoid_ambiguous_else(stmt) => {
p.print_soft_space();
p.print_block_start(stmt.span().start);
stmt.gen(p, ctx);
p.needs_semicolon = false;
p.print_block_end(stmt.span().end);
if if_stmt.alternate.is_some() {
p.print_soft_space();
} else {
p.print_soft_newline();
}
}
stmt => {
stmt.gen(p, ctx);
}
}
if if_stmt.alternate.is_some() {
p.print_soft_space();
} else {
p.print_soft_newline();
stmt => p.print_body(stmt, false, ctx),
}
if let Some(alternate) = if_stmt.alternate.as_ref() {
p.print_semicolon_if_needed();
p.print_space_before_identifier();
p.print_str(b"else ");
p.print_str(b"else");
match alternate {
Statement::BlockStatement(block) => {
p.print_soft_space();
p.print_block_statement(block, ctx);
p.print_soft_newline();
}
Statement::IfStatement(if_stmt) => {
p.print_hard_space();
print_if(if_stmt, p, ctx);
}
_ => {
p.print_soft_newline();
p.indent();
alternate.gen(p, ctx);
p.dedent();
}
stmt => p.print_body(stmt, true, ctx),
}
}
}
@ -296,12 +297,12 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ForStatement<'a> {
p.print_semicolon();
if let Some(update) = self.update.as_ref() {
p.print_soft_space();
p.print_expression(update);
}
p.print(b')');
p.print_soft_space();
p.print_body(&self.body, ctx);
p.print_body(&self.body, false, ctx);
}
}
@ -319,8 +320,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ForInStatement<'a> {
p.print_hard_space();
p.print_expression(&self.right);
p.print(b')');
p.print_soft_space();
p.print_body(&self.body, ctx);
p.print_body(&self.body, false, ctx);
}
}
@ -340,8 +340,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ForOfStatement<'a> {
p.print_str(b"of ");
self.right.gen_expr(p, Precedence::Assign, Context::default());
p.print(b')');
p.print_soft_space();
p.print_body(&self.body, ctx);
p.print_body(&self.body, false, ctx);
}
}
@ -370,8 +369,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for WhileStatement<'a> {
p.print(b'(');
p.print_expression(&self.test);
p.print(b')');
p.print_soft_space();
p.print_body(&self.body, ctx);
p.print_body(&self.body, false, ctx);
}
}
@ -470,12 +468,8 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for SwitchCase<'a> {
p.print_colon();
if self.consequent.len() == 1 {
if let Statement::BlockStatement(block) = &self.consequent[0] {
p.print_soft_space();
p.print_block_statement(block, ctx);
p.print_soft_newline();
return;
}
p.print_body(&self.consequent[0], false, ctx);
return;
}
p.print_soft_newline();
@ -503,12 +497,14 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ReturnStatement<'a> {
impl<'a, const MINIFY: bool> Gen<MINIFY> for LabeledStatement<'a> {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
p.add_source_mapping(self.span.start);
p.print_indent();
if !MINIFY && (p.indent > 0 || p.print_next_indent_as_space) {
p.add_source_mapping(self.span.start);
p.print_indent();
}
p.print_space_before_identifier();
self.label.gen(p, ctx);
p.print_colon();
p.print_soft_space();
p.print_body(&self.body, ctx);
p.print_body(&self.body, false, ctx);
}
}
@ -531,6 +527,9 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for TryStatement<'a> {
}
p.print_soft_space();
p.print_block_statement(&handler.body, ctx);
if self.finalizer.is_some() {
p.print_soft_newline();
}
}
if let Some(finalizer) = &self.finalizer {
p.print_soft_space();
@ -560,7 +559,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for WithStatement<'a> {
p.print(b'(');
p.print_expression(&self.object);
p.print(b')');
p.print_body(&self.body, ctx);
p.print_body(&self.body, false, ctx);
}
}
@ -716,6 +715,10 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ImportDeclaration<'a> {
}
if let Some(specifiers) = &self.specifiers {
if specifiers.is_empty() {
p.print_str(b"{}");
p.print_soft_space();
p.print_str(b"from");
p.print_soft_space();
p.print(b'\'');
p.print_str(self.source.value.as_bytes());
p.print(b'\'');
@ -732,19 +735,23 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ImportDeclaration<'a> {
match specifier {
ImportDeclarationSpecifier::ImportDefaultSpecifier(spec) => {
if in_block {
p.print_soft_space();
p.print_str(b"},");
in_block = false;
} else if index != 0 {
p.print_comma();
p.print_soft_space();
}
spec.local.gen(p, ctx);
}
ImportDeclarationSpecifier::ImportNamespaceSpecifier(spec) => {
if in_block {
p.print_soft_space();
p.print_str(b"},");
in_block = false;
} else if index != 0 {
p.print_comma();
p.print_soft_space();
}
p.print_str(b"* as ");
spec.local.gen(p, ctx);
@ -752,12 +759,15 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ImportDeclaration<'a> {
ImportDeclarationSpecifier::ImportSpecifier(spec) => {
if in_block {
p.print_comma();
p.print_soft_space();
} else {
if index != 0 {
p.print_comma();
p.print_soft_space();
}
in_block = true;
p.print(b'{');
p.print_soft_space();
}
if spec.import_kind.is_type() {
@ -785,6 +795,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ImportDeclaration<'a> {
}
}
if in_block {
p.print_soft_space();
p.print(b'}');
}
p.print_str(b" from ");
@ -825,6 +836,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ImportAttribute<'a> {
ImportAttributeKey::StringLiteral(literal) => literal.gen(p, ctx),
};
p.print_colon();
p.print_soft_space();
self.value.gen(p, ctx);
}
}
@ -1477,14 +1489,16 @@ impl<'a, const MINIFY: bool> GenExpr<MINIFY> for ObjectExpression<'a> {
fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, _precedence: Precedence, ctx: Context) {
let n = p.code_len();
p.wrap(p.start_of_stmt == n || p.start_of_arrow_expr == n, |p| {
let single_line = self.properties.is_empty();
let single_line = self.properties.len() <= 1;
p.print_curly_braces(self.span, single_line, |p| {
for (index, item) in self.properties.iter().enumerate() {
if index != 0 {
p.print_comma();
p.print_soft_newline();
}
p.print_indent();
if !single_line {
p.print_indent();
}
item.gen(p, ctx);
}
if !single_line {
@ -1691,9 +1705,10 @@ impl<'a, const MINIFY: bool> GenExpr<MINIFY> for BinaryExpression<'a> {
self.left.gen_expr(p, left_precedence, ctx);
if self.operator.is_keyword() {
p.print_space_before_identifier();
} else {
p.print_soft_space();
}
self.operator.gen(p, ctx);
p.print_soft_space();
let right_precedence = if self.precedence().is_left_associative() {
self.precedence()
} else {
@ -1714,6 +1729,7 @@ impl<const MINIFY: bool> Gen<MINIFY> for BinaryOperator {
let op: Operator = (*self).into();
p.print_space_before_operator(op);
p.print_str(operator);
p.print_soft_space();
p.prev_op = Some(op);
p.prev_op_end = p.code().len();
}
@ -1755,7 +1771,7 @@ impl<'a, const MINIFY: bool> GenExpr<MINIFY> for ConditionalExpression<'a> {
p.print_soft_space();
self.consequent.gen_expr(p, Precedence::Assign, ctx.and_in(true));
p.print_soft_space();
p.print(b':');
p.print_colon();
p.print_soft_space();
self.alternate.gen_expr(p, Precedence::Assign, ctx.union_in_if(wrap));
});
@ -1898,7 +1914,9 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for AssignmentTargetMaybeDefault<'a> {
impl<'a, const MINIFY: bool> Gen<MINIFY> for AssignmentTargetWithDefault<'a> {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
self.binding.gen(p, ctx);
p.print_soft_space();
p.print_equal();
p.print_soft_space();
self.init.gen_expr(p, Precedence::Assign, Context::default());
}
}
@ -1916,7 +1934,9 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for AssignmentTargetPropertyIdentifier<
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
self.binding.gen(p, ctx);
if let Some(expr) = &self.init {
p.print_soft_space();
p.print_equal();
p.print_soft_space();
expr.gen_expr(p, Precedence::Assign, Context::default());
}
}
@ -1938,6 +1958,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for AssignmentTargetPropertyProperty<'a
}
}
p.print_colon();
p.print_soft_space();
self.binding.gen(p, ctx);
}
}
@ -2157,7 +2178,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for JSXElementName<'a> {
impl<'a, const MINIFY: bool> Gen<MINIFY> for JSXNamespacedName<'a> {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
self.namespace.gen(p, ctx);
p.print(b':');
p.print_colon();
self.property.gen(p, ctx);
}
}
@ -2175,7 +2196,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for JSXAttribute<'a> {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
self.name.gen(p, ctx);
if let Some(value) = &self.value {
p.print(b'=');
p.print_equal();
value.gen(p, ctx);
}
}
@ -2326,6 +2347,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for StaticBlock<'a> {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
p.add_source_mapping(self.span.start);
p.print_str(b"static");
p.print_soft_space();
p.print_curly_braces(self.span, self.body.is_empty(), |p| {
for stmt in &self.body {
p.print_semicolon_if_needed();
@ -2487,6 +2509,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ObjectPattern<'a> {
fn gen(&self, p: &mut Codegen<MINIFY>, ctx: Context) {
p.add_source_mapping(self.span.start);
p.print(b'{');
p.print_soft_space();
p.print_list(&self.properties, ctx);
if let Some(rest) = &self.rest {
if !self.properties.is_empty() {
@ -2494,6 +2517,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ObjectPattern<'a> {
}
rest.gen(p, ctx);
}
p.print_soft_space();
p.print(b'}');
p.add_source_mapping(self.span.end);
}
@ -2513,6 +2537,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for BindingProperty<'a> {
}
if !self.shorthand {
p.print_colon();
p.print_soft_space();
}
self.value.gen(p, ctx);
}
@ -2876,12 +2901,15 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for TSTemplateLiteralType<'a> {
impl<'a, const MINIFY: bool> Gen<MINIFY> for TSTypeLiteral<'a> {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
p.print_curly_braces(self.span, self.members.is_empty(), |p| {
let single_line = self.members.len() <= 1;
p.print_curly_braces(self.span, single_line, |p| {
for item in &self.members {
p.print_indent();
item.gen(p, ctx);
p.print_semicolon();
p.print_soft_newline();
if !single_line {
p.print_semicolon();
p.print_soft_newline();
}
}
});
}

View file

@ -84,6 +84,7 @@ pub struct Codegen<'a, const MINIFY: bool> {
prev_op_end: usize,
prev_reg_exp_end: usize,
need_space_before_dot: usize,
print_next_indent_as_space: bool,
/// For avoiding `;` if the previous statement ends with `}`.
needs_semicolon: bool,
@ -95,7 +96,7 @@ pub struct Codegen<'a, const MINIFY: bool> {
start_of_default_export: usize,
/// Track the current indentation level
indentation: u8,
indent: u8,
// Builders
sourcemap_builder: Option<SourcemapBuilder>,
@ -139,13 +140,14 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
code: Vec::with_capacity(capacity),
needs_semicolon: false,
need_space_before_dot: 0,
print_next_indent_as_space: false,
prev_op_end: 0,
prev_reg_exp_end: 0,
prev_op: None,
start_of_stmt: 0,
start_of_arrow_expr: 0,
start_of_default_export: 0,
indentation: 0,
indent: 0,
sourcemap_builder,
move_comment_map: MoveCommentMap::default(),
}
@ -224,30 +226,36 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
self.move_comment_map.get(&start)
}
#[inline]
fn print_soft_space(&mut self) {
if !MINIFY {
self.print(b' ');
}
}
#[inline]
pub fn print_hard_space(&mut self) {
self.print(b' ');
}
#[inline]
fn print_soft_newline(&mut self) {
if !MINIFY {
self.print(b'\n');
}
}
#[inline]
fn print_semicolon(&mut self) {
self.print(b';');
}
#[inline]
fn print_comma(&mut self) {
self.print(b',');
}
#[inline]
fn print_space_before_identifier(&mut self) {
if self
.peek_nth(0)
@ -257,32 +265,41 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
}
}
#[inline]
fn peek_nth(&self, n: usize) -> Option<char> {
#[allow(unsafe_code)]
// SAFETY: criteria of `from_utf8_unchecked` are met.
unsafe { std::str::from_utf8_unchecked(self.code()) }.chars().nth_back(n)
}
#[inline]
fn indent(&mut self) {
if !MINIFY {
self.indentation += 1;
self.indent += 1;
}
}
#[inline]
fn dedent(&mut self) {
if !MINIFY {
self.indentation -= 1;
self.indent -= 1;
}
}
#[inline]
fn print_indent(&mut self) {
if !MINIFY {
for _ in 0..self.indentation {
self.print(b'\t');
}
if MINIFY {
return;
}
if self.print_next_indent_as_space {
self.print_hard_space();
self.print_next_indent_as_space = false;
return;
}
self.code.extend(std::iter::repeat(b'\t').take(self.indent as usize));
}
#[inline]
fn print_semicolon_after_statement(&mut self) {
if MINIFY {
self.needs_semicolon = true;
@ -291,6 +308,7 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
}
}
#[inline]
fn print_semicolon_if_needed(&mut self) {
if self.needs_semicolon {
self.print_semicolon();
@ -298,14 +316,17 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
}
}
#[inline]
fn print_ellipsis(&mut self) {
self.print_str(b"...");
}
#[inline]
pub fn print_colon(&mut self) {
self.print(b':');
}
#[inline]
fn print_equal(&mut self) {
self.print(b'=');
}
@ -351,13 +372,24 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
self.print(b'}');
}
fn print_body(&mut self, stmt: &Statement<'_>, ctx: Context) {
fn print_body(&mut self, stmt: &Statement<'_>, need_space: bool, ctx: Context) {
match stmt {
Statement::BlockStatement(stmt) => {
self.print_soft_space();
self.print_block_statement(stmt, ctx);
self.print_soft_newline();
}
stmt => stmt.gen(self, ctx),
Statement::EmptyStatement(_) => {
self.print_semicolon();
self.print_soft_newline();
}
stmt => {
if need_space && MINIFY {
self.print_hard_space();
}
self.print_next_indent_as_space = true;
stmt.gen(self, ctx);
}
}
}
@ -390,6 +422,7 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
}
}
#[inline]
pub fn print_expression(&mut self, expr: &Expression<'_>) {
expr.gen_expr(self, Precedence::lowest(), Context::default());
}
@ -422,10 +455,6 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
}
fn print_space_before_operator(&mut self, next: Operator) {
if !MINIFY {
self.print_hard_space();
return;
}
if self.prev_op_end != self.code.len() {
return;
}
@ -457,6 +486,7 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
}
}
#[inline]
fn wrap<F: FnMut(&mut Self)>(&mut self, wrap: bool, mut f: F) {
if wrap {
self.print(b'(');
@ -467,6 +497,7 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
}
}
#[inline]
fn wrap_quote<F: FnMut(&mut Self, char)>(&mut self, s: &str, mut f: F) {
let quote = choose_quote(s);
self.print(quote as u8);

View file

@ -121,7 +121,7 @@ fn template() {
fn module_decl() {
test("export * as foo from 'foo'", "export * as foo from 'foo';\n", None);
test("import x from './foo.js' with {}", "import x from './foo.js' with {\n};\n", None);
test("import {} from './foo.js' with {}", "import './foo.js' with {\n};\n", None);
test("import {} from './foo.js' with {}", "import {} from './foo.js' with {\n};\n", None);
test("export * from './foo.js' with {}", "export * from './foo.js' with {\n};\n", None);
}
@ -176,8 +176,12 @@ fn typescript() {
test_ts("function isString(value: unknown): asserts value is string {\n\tif (typeof value !== 'string') {\n\t\tthrow new Error('Not a string');\n\t}\n}", "function isString(value: unknown): asserts value is string {\n\tif (typeof value !== 'string') {\n\t\tthrow new Error('Not a string');\n\t}\n}\n", false);
// type-only imports/exports
test_ts("import type { Foo } from 'foo';", "import type {Foo} from 'foo';\n", false);
test_ts("import { Foo, type Bar } from 'foo';", "import {Foo,type Bar} from 'foo';\n", false);
test_ts("import type { Foo } from 'foo';", "import type { Foo } from 'foo';\n", false);
test_ts(
"import { Foo, type Bar } from 'foo';",
"import { Foo, type Bar } from 'foo';\n",
false,
);
test_ts(
"export { Foo, type Bar } from 'foo';",
"export { Foo, type Bar } from 'foo';\n",

File diff suppressed because it is too large Load diff

View file

@ -17,61 +17,49 @@ Mismatch: "declarationSingleFileHasErrorsReported.ts"
#### "declarationLinkedAliases.ts" ####
//// [declarationLinkedAliases.ts] ////
import {A} from 'mod';
import { A } from 'mod';
import B = A.C;
export { B };
//// [declarationLinkedAliases.d.ts] ////
import {A} from 'mod';
import { A } from 'mod';
import B = A.C;
export { B };
#### "declarationLocalAliasOfImportAlias.ts" ####
//// [declarationLocalAliasOfImportAlias.ts] ////
import {Record} from './a';
import { Record } from './a';
export type Foo<K extends string> = Record<K, number>;
export const obj = {
doThing<K extends string>(_k: K) {
return ({} as any);
}
};
export const obj = {doThing<K extends string>(_k: K) {
return ({} as any);
}};
//// [declarationLocalAliasOfImportAlias.d.ts] ////
import {Record} from './a';
import { Record } from './a';
export type Foo<K extends string> = Record<K, number>;
export declare const obj: {
doThing<K extends string>(_k: K): Foo<K>;
};
export declare const obj: {doThing<K extends string>(_k: K): Foo<K>};
#### "declarationSelfReferentialConstraint.ts" ####
//// [declarationSelfReferentialConstraint.ts] ////
export const object = {
foo: <T extends ((Set<T>) | ([]))>(): void => {}
};
export const object = {foo: <T extends ((Set<T>) | ([]))>(): void => {}};
//// [declarationSelfReferentialConstraint.d.ts] ////
export declare const object: {
foo: <T extends ((Set<T>) | ([]))>() => void;
};
export declare const object: {foo: <T extends ((Set<T>) | ([]))>() => void};
#### "declarationTypeParameterConstraint.ts" ####
//// [declarationTypeParameterConstraint.ts] ////
import {type In,type Out,type Base} from './a';
export const object = {
doThing<T extends Base>(_t: T, _in: In[T]) {
return;
}
};
import { type In, type Out, type Base } from './a';
export const object = {doThing<T extends Base>(_t: T, _in: In[T]) {
return;
}};
//// [declarationTypeParameterConstraint.d.ts] ////
import {type In,type Out,type Base} from './a';
export declare const object: {
doThing<T extends Base>(_t: T, _in: In[T]): Out[T];
};
import { type In, type Out, type Base } from './a';
export declare const object: {doThing<T extends Base>(_t: T, _in: In[T]): Out[T]};
#### "declarationTypeWithComputedName.ts" ####
//// [declarationTypeWithComputedName.ts] ////
import {Foo} from './a';
import { Foo } from './a';
export type Bar = {
[Foo.A]: 1;
[Foo.B]: 2;
@ -82,7 +70,7 @@ export const valBar = ((null as any) as {
});
//// [declarationTypeWithComputedName.d.ts] ////
import {Foo} from './a';
import { Foo } from './a';
export type Bar = {
[Foo.A]: 1;
[Foo.B]: 2;
@ -100,9 +88,7 @@ export const fn2 = (a: MissingGlobalType) => (null as MissingGlobalType);
export const x2: typeof missingGlobalValue = null;
export const fn3 = (a: typeof missingGlobalValue): typeof missingGlobalValue => null;
export const fn4 = (a: typeof missingGlobalValue) => (null as typeof missingGlobalValue);
export const o: {
[missingGlobalValue]: string;
} = null;
export const o: {[missingGlobalValue]: string} = null;
//// [declarationUnresolvedGlobalReferencesNoErrors.d.ts] ////
export declare const x: MissingGlobalType;
@ -111,18 +97,16 @@ export declare const fn2: (a: MissingGlobalType) => MissingGlobalType;
export declare const x2: typeof missingGlobalValue;
export declare const fn3: (a: typeof missingGlobalValue) => typeof missingGlobalValue;
export declare const fn4: (a: typeof missingGlobalValue) => typeof missingGlobalValue;
export declare const o: {
[missingGlobalValue]: string;
};
export declare const o: {[missingGlobalValue]: string};
#### "declarationUnresolvedTypeReference.ts" ####
//// [declarationUnresolvedTypeReference.ts] ////
import {type Type} from './a';
import { type Type } from './a';
export const foo = (_: Type): void => {};
export const bar = (_: import('./a').Type): void => {};
//// [declarationUnresolvedTypeReference.d.ts] ////
import {type Type} from './a';
import { type Type } from './a';
export declare const foo: (_: Type) => void;
export declare const bar: (_: import('./a').Type) => void;
@ -153,12 +137,8 @@ export const c: number = 1;
export interface A {
x: number;
}
let expr: {
x: number;
};
expr = {
x: 12
};
let expr: {x: number};
expr = {x: 12};
export default expr;
//// [declarationsSimple.d.ts] ////
@ -166,7 +146,5 @@ export declare const c: number;
export interface A {
x: number;
}
declare let expr: {
x: number;
};
declare let expr: {x: number};
export default expr;

View file

@ -1,6 +1,6 @@
commit: 12619ffe
Passed: 478/927
Passed: 474/927
# All Passed:
* babel-preset-react
@ -445,12 +445,16 @@ Passed: 478/927
* opts/optimizeConstEnums/input.ts
* opts/rewriteImportExtensions/input.ts
# babel-plugin-transform-typescript (134/151)
# babel-plugin-transform-typescript (130/151)
* enum/mix-references/input.ts
* enum/ts5.0-const-foldable/input.ts
* exports/declared-types/input.ts
* exports/interface/input.ts
* imports/elide-no-import-specifiers/input.ts
* imports/import-removed-exceptions/input.ts
* imports/only-remove-type-imports/input.ts
* imports/type-only-export-specifier-2/input.ts
* imports/type-only-import-specifier-4/input.ts
* optimize-const-enums/custom-values/input.ts
* optimize-const-enums/custom-values-exported/input.ts
* optimize-const-enums/declare/input.ts