diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts
index 5b955d2492..eec693bbb6 100644
--- a/src/services/codefixes/helpers.ts
+++ b/src/services/codefixes/helpers.ts
@@ -112,27 +112,23 @@ namespace ts.codefix {
export function createMethodFromCallExpression(
context: CodeFixContextBase,
- { typeArguments, arguments: args, parent: parent }: CallExpression,
+ call: CallExpression,
methodName: string,
inJs: boolean,
makeStatic: boolean,
preferences: UserPreferences,
body: boolean,
): MethodDeclaration {
+ const { typeArguments, arguments: args, parent } = call;
const checker = context.program.getTypeChecker();
- const types = map(args,
- arg => {
- let type = checker.getTypeAtLocation(arg);
- if (type === undefined) {
- return undefined;
- }
- // Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {"
- type = checker.getBaseTypeOfLiteralType(type);
- return checker.typeToTypeNode(type);
- });
+ const types = map(args, arg =>
+ // Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {"
+ checker.typeToTypeNode(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(arg))));
const names = map(args, arg =>
isIdentifier(arg) ? arg.text :
- isPropertyAccessExpression(arg) ? arg.name.text : undefined);
+ isPropertyAccessExpression(arg) ? arg.name.text : undefined);
+ const contextualType = checker.getContextualType(call);
+ const returnType = inJs ? undefined : contextualType && checker.typeToTypeNode(contextualType, call) || createKeywordTypeNode(SyntaxKind.AnyKeyword);
return createMethod(
/*decorators*/ undefined,
/*modifiers*/ makeStatic ? [createToken(SyntaxKind.StaticKeyword)] : undefined,
@@ -142,7 +138,7 @@ namespace ts.codefix {
/*typeParameters*/ inJs ? undefined : map(typeArguments, (_, i) =>
createTypeParameterDeclaration(CharacterCodes.T + typeArguments!.length - 1 <= CharacterCodes.Z ? String.fromCharCode(CharacterCodes.T + i) : `T${i}`)),
/*parameters*/ createDummyParameters(args.length, names, types, /*minArgumentCount*/ undefined, inJs),
- /*type*/ inJs ? undefined : createKeywordTypeNode(SyntaxKind.AnyKeyword),
+ /*type*/ returnType,
body ? createStubbedMethodBody(preferences) : undefined);
}
diff --git a/tests/cases/fourslash/codeFixAddMissingMember10.ts b/tests/cases/fourslash/codeFixAddMissingMember10.ts
new file mode 100644
index 0000000000..990d86ec49
--- /dev/null
+++ b/tests/cases/fourslash/codeFixAddMissingMember10.ts
@@ -0,0 +1,16 @@
+///
+
+//// class C {}
+//// const n: number = new C().add(1, 2);
+
+verify.codeFixAll({
+ fixId: "addMissingMember",
+ fixAllDescription: "Add all missing members",
+ newFileContent:
+`class C {
+ add(arg0: number, arg1: number): number {
+ throw new Error("Method not implemented.");
+ }
+}
+const n: number = new C().add(1, 2);`,
+});
diff --git a/tests/cases/fourslash/codeFixAddMissingMember11.ts b/tests/cases/fourslash/codeFixAddMissingMember11.ts
new file mode 100644
index 0000000000..6f68502d4c
--- /dev/null
+++ b/tests/cases/fourslash/codeFixAddMissingMember11.ts
@@ -0,0 +1,18 @@
+///
+
+//// class C {}
+//// function f(v: number): void { }
+//// f(new C().add(1, 2))
+
+verify.codeFixAll({
+ fixId: "addMissingMember",
+ fixAllDescription: "Add all missing members",
+ newFileContent:
+`class C {
+ add(arg0: number, arg1: number): number {
+ throw new Error("Method not implemented.");
+ }
+}
+function f(v: number): void { }
+f(new C().add(1, 2))`,
+});