diff --git a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts
index 695e71b53c2..ddd5bacea26 100644
--- a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts
+++ b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts
@@ -54,6 +54,7 @@ namespace ts.codefix {
const nonPrivateAndNotExistedInHeritageClauseMembers = implementedTypeSymbols.filter(and(symbolPointsToNonPrivateMember, symbol => !maybeHeritageClauseSymbol.has(symbol.escapedName)));
const classType = checker.getTypeAtLocation(classDeclaration);
+ const constructor = find(classDeclaration.members, m => isConstructorDeclaration(m));
if (!classType.getNumberIndexType()) {
createMissingIndexSignatureDeclaration(implementedType, IndexKind.Number);
@@ -62,12 +63,22 @@ namespace ts.codefix {
createMissingIndexSignatureDeclaration(implementedType, IndexKind.String);
}
- createMissingMemberNodes(classDeclaration, nonPrivateAndNotExistedInHeritageClauseMembers, context, preferences, member => changeTracker.insertNodeAtClassStart(sourceFile, classDeclaration, member));
+ createMissingMemberNodes(classDeclaration, nonPrivateAndNotExistedInHeritageClauseMembers, context, preferences, member => insertInterfaceMemberNode(sourceFile, classDeclaration, member));
function createMissingIndexSignatureDeclaration(type: InterfaceType, kind: IndexKind): void {
const indexInfoOfKind = checker.getIndexInfoOfType(type, kind);
if (indexInfoOfKind) {
- changeTracker.insertNodeAtClassStart(sourceFile, classDeclaration, checker.indexInfoToIndexSignatureDeclaration(indexInfoOfKind, kind, classDeclaration, /*flags*/ undefined, getNoopSymbolTrackerWithResolver(context))!);
+ insertInterfaceMemberNode(sourceFile, classDeclaration, checker.indexInfoToIndexSignatureDeclaration(indexInfoOfKind, kind, classDeclaration, /*flags*/ undefined, getNoopSymbolTrackerWithResolver(context))!);
+ }
+ }
+
+ // Either adds the node at the top of the class, or if there's a constructor right after that
+ function insertInterfaceMemberNode(sourceFile: SourceFile, cls: ClassLikeDeclaration | InterfaceDeclaration, newElement: ClassElement): void {
+ if (constructor) {
+ changeTracker.insertNodeAfter(sourceFile, constructor, newElement);
+ }
+ else {
+ changeTracker.insertNodeAtClassStart(sourceFile, cls, newElement);
}
}
}
diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceEmptyTypeLiteral.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceEmptyTypeLiteral.ts
index 98059017098..6a8a48266ef 100644
--- a/tests/cases/fourslash/codeFixClassImplementInterfaceEmptyTypeLiteral.ts
+++ b/tests/cases/fourslash/codeFixClassImplementInterfaceEmptyTypeLiteral.ts
@@ -1,5 +1,6 @@
///
+////
//// interface I {
//// x: {};
//// }
@@ -8,6 +9,15 @@
//// |]constructor() { }
//// }
-verify.rangeAfterCodeFix(`
-x: {};
-`);
+verify.codeFix({
+ description: "Implement interface 'I'",
+ newFileContent:`
+interface I {
+ x: {};
+}
+
+class C implements I {
+ constructor() { }
+ x: {};
+}`,
+});
diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceSomePropertiesPresent.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceSomePropertiesPresent.ts
index e667783b995..4b61ea41e40 100644
--- a/tests/cases/fourslash/codeFixClassImplementInterfaceSomePropertiesPresent.ts
+++ b/tests/cases/fourslash/codeFixClassImplementInterfaceSomePropertiesPresent.ts
@@ -1,5 +1,6 @@
///
+////
//// interface I {
//// x: number;
//// y: number;
@@ -11,6 +12,20 @@
//// y: number;
//// }
-verify.rangeAfterCodeFix(`
-z: number & { __iBrand: any; };
-`);
+
+verify.codeFix({
+ description: "Implement interface 'I'",
+ newFileContent:`
+interface I {
+ x: number;
+ y: number;
+ z: number & { __iBrand: any };
+}
+
+class C implements I {
+ constructor(public x: number) { }
+ z: number & { __iBrand: any; };
+ y: number;
+}`,
+});
+
diff --git a/tests/cases/fourslash/codeFixClassImplementInterface_order.ts b/tests/cases/fourslash/codeFixClassImplementInterface_order.ts
new file mode 100644
index 00000000000..7e45eeb6cf6
--- /dev/null
+++ b/tests/cases/fourslash/codeFixClassImplementInterface_order.ts
@@ -0,0 +1,28 @@
+///
+
+// #34841
+
+////interface IFoo {
+//// bar(): void;
+////}
+////
+////class Foo implements IFoo {
+//// private x = 1;
+//// constructor() { this.x = 2 }
+////}
+
+verify.codeFix({
+ description: "Implement interface 'IFoo'",
+ index: 0,
+ newFileContent:
+`interface IFoo {
+ bar(): void;
+}
+
+class Foo implements IFoo {
+ private x = 1;
+ constructor() { this.x = 2 }
+ bar(): void {
+ throw new Error("Method not implemented.");
+ }
+}`});