Skip to content

Commit 8ba5019

Browse files
KingwlAndy
authored andcommitted
try get add missing member return type from context (microsoft#26250)
* try get add missing member return type from context * support contextual type
1 parent 65da7e9 commit 8ba5019

File tree

3 files changed

+43
-13
lines changed

3 files changed

+43
-13
lines changed

src/services/codefixes/helpers.ts

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -112,27 +112,23 @@ namespace ts.codefix {
112112

113113
export function createMethodFromCallExpression(
114114
context: CodeFixContextBase,
115-
{ typeArguments, arguments: args, parent: parent }: CallExpression,
115+
call: CallExpression,
116116
methodName: string,
117117
inJs: boolean,
118118
makeStatic: boolean,
119119
preferences: UserPreferences,
120120
body: boolean,
121121
): MethodDeclaration {
122+
const { typeArguments, arguments: args, parent } = call;
122123
const checker = context.program.getTypeChecker();
123-
const types = map(args,
124-
arg => {
125-
let type = checker.getTypeAtLocation(arg);
126-
if (type === undefined) {
127-
return undefined;
128-
}
129-
// Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {"
130-
type = checker.getBaseTypeOfLiteralType(type);
131-
return checker.typeToTypeNode(type);
132-
});
124+
const types = map(args, arg =>
125+
// Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {"
126+
checker.typeToTypeNode(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(arg))));
133127
const names = map(args, arg =>
134128
isIdentifier(arg) ? arg.text :
135-
isPropertyAccessExpression(arg) ? arg.name.text : undefined);
129+
isPropertyAccessExpression(arg) ? arg.name.text : undefined);
130+
const contextualType = checker.getContextualType(call);
131+
const returnType = inJs ? undefined : contextualType && checker.typeToTypeNode(contextualType, call) || createKeywordTypeNode(SyntaxKind.AnyKeyword);
136132
return createMethod(
137133
/*decorators*/ undefined,
138134
/*modifiers*/ makeStatic ? [createToken(SyntaxKind.StaticKeyword)] : undefined,
@@ -142,7 +138,7 @@ namespace ts.codefix {
142138
/*typeParameters*/ inJs ? undefined : map(typeArguments, (_, i) =>
143139
createTypeParameterDeclaration(CharacterCodes.T + typeArguments!.length - 1 <= CharacterCodes.Z ? String.fromCharCode(CharacterCodes.T + i) : `T${i}`)),
144140
/*parameters*/ createDummyParameters(args.length, names, types, /*minArgumentCount*/ undefined, inJs),
145-
/*type*/ inJs ? undefined : createKeywordTypeNode(SyntaxKind.AnyKeyword),
141+
/*type*/ returnType,
146142
body ? createStubbedMethodBody(preferences) : undefined);
147143
}
148144

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
//// class C {}
4+
//// const n: number = new C().add(1, 2);
5+
6+
verify.codeFixAll({
7+
fixId: "addMissingMember",
8+
fixAllDescription: "Add all missing members",
9+
newFileContent:
10+
`class C {
11+
add(arg0: number, arg1: number): number {
12+
throw new Error("Method not implemented.");
13+
}
14+
}
15+
const n: number = new C().add(1, 2);`,
16+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
//// class C {}
4+
//// function f(v: number): void { }
5+
//// f(new C().add(1, 2))
6+
7+
verify.codeFixAll({
8+
fixId: "addMissingMember",
9+
fixAllDescription: "Add all missing members",
10+
newFileContent:
11+
`class C {
12+
add(arg0: number, arg1: number): number {
13+
throw new Error("Method not implemented.");
14+
}
15+
}
16+
function f(v: number): void { }
17+
f(new C().add(1, 2))`,
18+
});

0 commit comments

Comments
 (0)