mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-03-16 06:28:12 -05:00
fix(47582): skip extraction if the type node is in the range of the type parameter declaration (#47596)
This commit is contained in:
@@ -144,11 +144,20 @@ namespace ts.refactor {
|
||||
function visitor(node: Node): true | undefined {
|
||||
if (isTypeReferenceNode(node)) {
|
||||
if (isIdentifier(node.typeName)) {
|
||||
const symbol = checker.resolveName(node.typeName.text, node.typeName, SymbolFlags.TypeParameter, /* excludeGlobals */ true);
|
||||
const declaration = tryCast(symbol?.declarations?.[0], isTypeParameterDeclaration);
|
||||
if (declaration) {
|
||||
if (rangeContainsSkipTrivia(statement, declaration, file) && !rangeContainsSkipTrivia(selection, declaration, file)) {
|
||||
pushIfUnique(result, declaration);
|
||||
const typeName = node.typeName;
|
||||
const symbol = checker.resolveName(typeName.text, typeName, SymbolFlags.TypeParameter, /* excludeGlobals */ true);
|
||||
for (const decl of symbol?.declarations || emptyArray) {
|
||||
if (isTypeParameterDeclaration(decl) && decl.getSourceFile() === file) {
|
||||
// skip extraction if the type node is in the range of the type parameter declaration.
|
||||
// function foo<T extends { a?: /**/T }>(): void;
|
||||
if (decl.name.escapedText === typeName.escapedText && rangeContainsSkipTrivia(decl, selection, file)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rangeContainsSkipTrivia(statement, decl, file) && !rangeContainsSkipTrivia(selection, decl, file)) {
|
||||
pushIfUnique(result, decl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
6
tests/cases/fourslash/refactorExtractType72.ts
Normal file
6
tests/cases/fourslash/refactorExtractType72.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////export declare function foo<T extends { a?: /*a*/T/*b*/ }>(): void;
|
||||
|
||||
goTo.select("a", "b");
|
||||
verify.not.refactorAvailable("Extract type", "Extract to type alias");
|
||||
11
tests/cases/fourslash/refactorExtractType73.ts
Normal file
11
tests/cases/fourslash/refactorExtractType73.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @Filename: a.ts
|
||||
////interface Foo<T extends { prop: T }> {}
|
||||
|
||||
// @Filename: b.ts
|
||||
////interface Foo<T extends { prop: /*a*/T/*b*/ }> {}
|
||||
|
||||
goTo.file("b.ts");
|
||||
goTo.select("a", "b");
|
||||
verify.not.refactorAvailable("Extract type", "Extract to type alias");
|
||||
15
tests/cases/fourslash/refactorExtractType74.ts
Normal file
15
tests/cases/fourslash/refactorExtractType74.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @Filename: a.ts
|
||||
//// interface Foo<T extends { prop: [|T|] }> {}
|
||||
|
||||
// @Filename: b.ts
|
||||
//// // Some initial comments.
|
||||
//// // We need to ensure these files have different contents,
|
||||
//// // so their ranges differ, so we'll start a few lines below in this file.
|
||||
//// interface Foo<T extends { prop: [|T|] }> {}
|
||||
|
||||
for (const range of test.ranges()) {
|
||||
goTo.selectRange(range);
|
||||
verify.not.refactorAvailable("Extract type", "Extract to type alias");
|
||||
}
|
||||
9
tests/cases/fourslash/refactorExtractType75.ts
Normal file
9
tests/cases/fourslash/refactorExtractType75.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @Filename: a.ts
|
||||
//// interface Foo<T extends { prop: T }> {}
|
||||
//// interface Foo<T extends { prop: /*a*/T/*b*/ }> {}
|
||||
|
||||
goTo.file("a.ts");
|
||||
goTo.select("a", "b");
|
||||
verify.not.refactorAvailable("Extract type", "Extract to type alias");
|
||||
Reference in New Issue
Block a user