Skip to content
Closed
41 changes: 35 additions & 6 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6329,8 +6329,25 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {

const firstIdentifier = getFirstIdentifier(entityName);
const symbol = resolveName(enclosingDeclaration, firstIdentifier.escapedText, meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false);
if (symbol && symbol.flags & SymbolFlags.TypeParameter && meaning & SymbolFlags.Type) {
return { accessibility: SymbolAccessibility.Accessible };
if (symbol) {
if (symbol.flags & SymbolFlags.TypeParameter && meaning & SymbolFlags.Type) {
return { accessibility: SymbolAccessibility.Accessible };
}

// Parameters or binding elements from parameters are always visible in their enclosing function declarations

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The checker complained about the parameter name not being accessible (since arrow functions are not themselves marked as visible by determineIfDeclarationIsVisible.

if (symbol.flags & SymbolFlags.FunctionScopedVariable && meaning & SymbolFlags.Value) {
let declaration: Node | undefined = symbol.valueDeclaration;
while (declaration) {
if (declaration.kind === SyntaxKind.Parameter) break;
if (declaration.kind === SyntaxKind.BindingElement) {
declaration = declaration.parent.parent;
}
break;
}
if (declaration?.kind === SyntaxKind.Parameter) {
return { accessibility: SymbolAccessibility.Accessible };
}
}
}
if (!symbol && isThisIdentifier(firstIdentifier) && isSymbolAccessible(getSymbolOfDeclaration(getThisContainer(firstIdentifier, /*includeArrowFunctions*/ false, /*includeClassComputedPropertyName*/ false)), firstIdentifier, meaning, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === SymbolAccessibility.Accessible) {
return { accessibility: SymbolAccessibility.Accessible };
Expand Down Expand Up @@ -48160,13 +48177,25 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
hasSyntacticModifier(parameter, ModifierFlags.ParameterPropertyModifier);
}

function isExpandoFunctionDeclaration(node: Declaration): boolean {
const declaration = getParseTreeNode(node, isFunctionDeclaration);
function isExpandoFunctionDeclaration(node: FunctionDeclaration | VariableDeclaration): boolean {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both function and variable declarations will now be tested. We can't reliably determine the type for an expando functions variable from just it's declaration so we fall back on the type checker.

const declaration = getParseTreeNode(node, isDeclaration);
if (!declaration) {
return false;
}
const symbol = getSymbolOfDeclaration(declaration);
if (!symbol || !(symbol.flags & SymbolFlags.Function)) {
let symbol: Symbol;
if (isVariableDeclaration(declaration)) {
if (declaration.type || !isVarConstLike(declaration)) {
return false;
}
if (!(declaration.initializer && isFunctionExpressionOrArrowFunction(declaration.initializer))) {
return false;
}
symbol = getSymbolOfDeclaration(declaration.initializer);
}
else {
symbol = getSymbolOfDeclaration(declaration);
}
if (!symbol || !(symbol.flags & SymbolFlags.Function | SymbolFlags.Variable)) {
return false;
}
return !!forEachEntry(getExportsOfSymbol(symbol), p => p.flags & SymbolFlags.Value && isExpandoPropertyDeclaration(p.valueDeclaration));
Expand Down
Loading