@@ -946,6 +946,7 @@ namespace ts.refactor.extractMethod {
946
946
substitutionsPerScope . push ( createMap < Expression > ( ) ) ;
947
947
errorsPerScope . push ( [ ] ) ;
948
948
}
949
+
949
950
const seenUsages = createMap < Usage > ( ) ;
950
951
const target = isReadonlyArray ( targetRange . range ) ? createBlock ( < Statement [ ] > targetRange . range ) : targetRange . range ;
951
952
const containingLexicalScopeOfExtraction = isBlockScope ( scopes [ 0 ] , scopes [ 0 ] . parent ) ? scopes [ 0 ] : getEnclosingBlockScopeContainer ( scopes [ 0 ] ) ;
@@ -955,6 +956,14 @@ namespace ts.refactor.extractMethod {
955
956
956
957
collectUsages ( target ) ;
957
958
959
+ // Unfortunately, this code takes advantage of the knowledge that the generated method
960
+ // will use the contextual type of an expression as the return type of the extracted
961
+ // method (and will therefore "use" all the types involved).
962
+ if ( inGenericContext && ! isReadonlyArray ( targetRange . range ) ) {
963
+ const contextualType = checker . getContextualType ( targetRange . range ) ;
964
+ recordTypeParameterUsages ( contextualType ) ;
965
+ }
966
+
958
967
if ( allTypeParameterUsages . size > 0 ) {
959
968
const seenTypeParameterUsages = createMap < TypeParameter > ( ) ; // Key is type ID
960
969
@@ -1032,18 +1041,21 @@ namespace ts.refactor.extractMethod {
1032
1041
return false ;
1033
1042
}
1034
1043
1044
+ function recordTypeParameterUsages ( type : Type ) {
1045
+ const symbolWalker = checker . getSymbolWalker ( ) ;
1046
+ const { visitedTypes} = symbolWalker . walkType ( type ) ;
1047
+
1048
+ for ( const visitedType of visitedTypes ) {
1049
+ if ( visitedType . flags & TypeFlags . TypeParameter ) {
1050
+ allTypeParameterUsages . set ( visitedType . id . toString ( ) , visitedType as TypeParameter ) ;
1051
+ }
1052
+ }
1053
+ }
1054
+
1035
1055
function collectUsages ( node : Node , valueUsage = Usage . Read ) {
1036
1056
if ( inGenericContext ) {
1037
1057
const type = checker . getTypeAtLocation ( node ) ;
1038
-
1039
- const symbolWalker = checker . getSymbolWalker ( ) ;
1040
- const { visitedTypes} = symbolWalker . walkType ( type ) ;
1041
-
1042
- for ( const visitedType of visitedTypes ) {
1043
- if ( visitedType . flags & TypeFlags . TypeParameter ) {
1044
- allTypeParameterUsages . set ( visitedType . id . toString ( ) , visitedType as TypeParameter ) ;
1045
- }
1046
- }
1058
+ recordTypeParameterUsages ( type ) ;
1047
1059
}
1048
1060
1049
1061
if ( isDeclaration ( node ) && node . symbol ) {
0 commit comments