@@ -476,15 +476,41 @@ 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+ // parameters are visible only inside function body, parameter list and return type
496+ // technically for parameter list case here we might mix parameters and variables declared in function,
497+ // however it is detected separately when checking initializers of parameters
498+ // to make sure that they reference no variables declared after them.
499+ useResult =
500+ lastLocation.kind === SyntaxKind.Parameter ||
501+ (
502+ lastLocation === (<FunctionLikeDeclaration>location).type &&
503+ result.valueDeclaration.kind === SyntaxKind.Parameter
504+ );
505+ }
506+ }
507+
508+ if (useResult) {
485509 break loop;
486510 }
487- result = undefined;
511+ else {
512+ result = undefined;
513+ }
488514 }
489515 }
490516 switch (location.kind) {
@@ -3829,7 +3855,13 @@ namespace ts {
38293855 let minArgumentCount = -1;
38303856 for (let i = 0, n = declaration.parameters.length; i < n; i++) {
38313857 const param = declaration.parameters[i];
3832- parameters.push(param.symbol);
3858+ let paramSymbol = param.symbol;
3859+ // Include parameter symbol instead of property symbol in the signature
3860+ if (paramSymbol && !!(paramSymbol.flags & SymbolFlags.Property) && !isBindingPattern(param.name)) {
3861+ const resolvedSymbol = resolveName(param, paramSymbol.name, SymbolFlags.Value, undefined, undefined);
3862+ paramSymbol = resolvedSymbol;
3863+ }
3864+ parameters.push(paramSymbol);
38333865 if (param.type && param.type.kind === SyntaxKind.StringLiteral) {
38343866 hasStringLiterals = true;
38353867 }
@@ -9873,7 +9905,7 @@ namespace ts {
98739905 return type;
98749906 }
98759907
9876- function checkFunctionExpressionOrObjectLiteralMethodBody(node: FunctionExpression | MethodDeclaration) {
9908+ function checkFunctionExpressionOrObjectLiteralMethodBody(node: ArrowFunction | FunctionExpression | MethodDeclaration) {
98779909 Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
98789910
98799911 const isAsync = isAsyncFunctionLike(node);
0 commit comments