Skip to content

Commit 255951c

Browse files
committed
Stop preventing extraction when a type parameter wouldn't bind
...correctly in a containing scope. It's not an issue because we'll just declare a corresponding type parameter on the extracted function and pass the original as a type argument. Fixes #18142
1 parent 34576c2 commit 255951c

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

src/harness/unittests/extractMethods.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,11 @@ function parseUnaryExpression(operator: string): UnaryExpression {
728728
729729
function parsePrimaryExpression(): any {
730730
throw "Not implemented";
731+
}`);
732+
// Type parameter as declared type
733+
testExtractMethod("extractMethod30",
734+
`function F<T>() {
735+
[#|let t: T;|]
731736
}`);
732737
});
733738

src/services/refactors/extractMethod.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1222,7 +1222,11 @@ namespace ts.refactor.extractMethod {
12221222
substitutionsPerScope[i].set(symbolId, substitution);
12231223
}
12241224
else if (isTypeName) {
1225-
errorsPerScope[i].push(createDiagnosticForNode(identifier, Messages.TypeWillNotBeVisibleInTheNewScope));
1225+
// If the symbol is a type parameter that won't be in scope, we'll pass it as a type argument
1226+
// so there's no problem.
1227+
if (!(symbol.flags & SymbolFlags.TypeParameter)) {
1228+
errorsPerScope[i].push(createDiagnosticForNode(identifier, Messages.TypeWillNotBeVisibleInTheNewScope));
1229+
}
12261230
}
12271231
else {
12281232
usagesPerScope[i].usages.set(identifier.text as string, { usage, symbol, node: identifier });
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// ==ORIGINAL==
2+
function F<T>() {
3+
let t: T;
4+
}
5+
// ==SCOPE::inner function in function 'F'==
6+
function F<T>() {
7+
/*RENAME*/newFunction();
8+
9+
function newFunction() {
10+
let t: T;
11+
}
12+
}
13+
// ==SCOPE::function in global scope==
14+
function F<T>() {
15+
/*RENAME*/newFunction<T>();
16+
}
17+
function newFunction<T>() {
18+
let t: T;
19+
}

0 commit comments

Comments
 (0)