diff --git a/lib/printer.ts b/lib/printer.ts index a53f1e76..ae7c9030 100644 --- a/lib/printer.ts +++ b/lib/printer.ts @@ -2424,12 +2424,11 @@ function genericPrintNoParens(path: any, options: any, print: any) { ]); case "TSInterfaceBody": { - const lines = fromString(";\n").join(path.map(print, "body")); + const lines = fromString("\n").join(path.map(print, "body")); if (lines.isEmpty()) { return fromString("{}", options); } - - return concat(["{\n", lines.indent(options.tabWidth), ";", "\n}"]); + return concat(["{\n", lines.indent(options.tabWidth), "\n}"]); } case "TSImportType": diff --git a/test/typescript.ts b/test/typescript.ts index 54b22668..a776d7aa 100644 --- a/test/typescript.ts +++ b/test/typescript.ts @@ -213,23 +213,23 @@ const nodeMajorVersion = parseInt(process.versions.node, 10); check([ "interface LabelledContainer {", - " label: string;", - " content: T;", - " option?: boolean;", - " readonly x: number;", - " [index: number]: string;", - " [propName: string]: any;", - " readonly [index: number]: string;", - " (source: string, subString: string): boolean;", - " (start: number): string;", - " reset(): void;", - " a(c: (this: void, e: E) => void): void;", + " label: string", + " content: T", + " option?: boolean", + " readonly x: number", + " [index: number]: string", + " [propName: string]: any", + " readonly [index: number]: string", + " (source: string, subString: string): boolean", + " (start: number): string", + " reset(): void", + " a(c: (this: void, e: E) => void): void", "}", ]); check([ "interface Square extends Shape, Visible {", - " sideLength: number;", + " sideLength: number", "}", ]); @@ -257,17 +257,17 @@ const nodeMajorVersion = parseInt(process.versions.node, 10); "}", ]); - check(["export interface S {", " i(s: string): boolean;", "}"]); + check(["export interface S {", " i(s: string): boolean", "}"]); check([ "namespace Validation {", " export interface S {", - " i(j: string): boolean;", + " i(j: string): boolean", " }", "}", ]); - check(["export interface S {", " i(j: string): boolean;", "}"]); + check(["export interface S {", " i(j: string): boolean", "}"]); check(["declare namespace D3 {", " export const f: number = 2;", "}"]); @@ -307,6 +307,68 @@ const nodeMajorVersion = parseInt(process.versions.node, 10); "type Alpha = Color.a;", ]); }); + + it("InterfaceBody: duplicate semicolon", function () { + const code = [ + "interface Hello {", + " 'hello': any;", + " 'hello': string;", + "}", + ].join(eol); + + const ast = recast.parse(code, { parser }); + + ast.program.body[0].body.body.pop(); + + assert.strictEqual( + recast.print(ast).code, + [ + "interface Hello {", + " 'hello': any;", + "}", + ].join(eol), + ); + }); + + it("InterfaceBody: duplicate semicolon: a lot of properties", function () { + const code = [ + "interface LabelledContainer {", + " label: string;", + " content: T;", + " option?: boolean;", + " readonly x: number;", + " [index: number]: string;", + " [propName: string]: any;", + " readonly [index: number]: string;", + " (source: string, subString: string): boolean;", + " (start: number): string;", + " reset(): void;", + " a(c: (this: void, e: E) => void): void;", + "}", + ].join(eol); + + const ast = recast.parse(code, { parser }); + + ast.program.body[0].body.body.shift(); + + assert.strictEqual( + recast.print(ast).code, + [ + "interface LabelledContainer {", + " content: T;", + " option?: boolean;", + " readonly x: number;", + " [index: number]: string;", + " [propName: string]: any;", + " readonly [index: number]: string;", + " (source: string, subString: string): boolean;", + " (start: number): string;", + " reset(): void;", + " a(c: (this: void, e: E) => void): void;", + "}", + ].join(eol), + ); + }); }); testReprinting(