@@ -476,15 +476,37 @@ namespace ts {
476476 // Locals of a source file are not in scope (because they get merged into the global symbol table)
477477 if (location.locals && !isGlobalSourceFile(location)) {
478478 if (result = getSymbol(location.locals, name, meaning)) {
479- // Type parameters of a function are in scope in the entire function declaration, including the parameter
480- // list and return type. However, local types are only in scope in the function body.
481- if (!(meaning & SymbolFlags.Type) ||
482- !(result.flags & (SymbolFlags.Type & ~SymbolFlags.TypeParameter)) ||
483- !isFunctionLike(location) ||
484- lastLocation === (<FunctionLikeDeclaration>location).body) {
479+ let useResult = true;
480+ if (isFunctionLike(location) && lastLocation && lastLocation !== (<FunctionLikeDeclaration>location).body) {
481+ // symbol lookup restrictions for function-like declarations
482+ // - Type parameters of a function are in scope in the entire function declaration, including the parameter
483+ // list and return type. However, local types are only in scope in the function body.
484+ // - parameters are only in the scope of function body
485+ if (meaning & result.flags & SymbolFlags.Type) {
486+ useResult = result.flags & SymbolFlags.TypeParameter
487+ // type parameters are visible in parameter list, return type and type parameter list
488+ ? lastLocation === (<FunctionLikeDeclaration>location).type ||
489+ lastLocation.kind === SyntaxKind.Parameter ||
490+ lastLocation.kind === SyntaxKind.TypeParameter
491+ // local types not visible outside the function body
492+ : false;
493+ }
494+ if (meaning & SymbolFlags.Value && result.flags & SymbolFlags.FunctionScopedVariable) {
495+ // function scoped variables are visible only inside function body and parameter list
496+ // technically here we might mix parameters and variables declared in function,
497+ // however this case is detected separately when checking initializers of parameters
498+ // to make sure that they reference no variables declared after them.
499+ useResult = lastLocation === (<FunctionLikeDeclaration>location).type ||
500+ lastLocation.kind === SyntaxKind.Parameter;
501+ }
502+ }
503+
504+ if (useResult) {
485505 break loop;
486506 }
487- result = undefined;
507+ else {
508+ result = undefined;
509+ }
488510 }
489511 }
490512 switch (location.kind) {
0 commit comments