diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e6a794e866a..6f541461b09 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1312,7 +1312,10 @@ namespace ts { case SyntaxKind.ClassDeclaration: case SyntaxKind.ClassExpression: case SyntaxKind.InterfaceDeclaration: - if (result = lookup(getMembersOfSymbol(getSymbolOfNode(location as ClassLikeDeclaration | InterfaceDeclaration)), name, meaning & SymbolFlags.Type)) { + // The below is used to lookup type parameters within a class or interface, as they are added to the class/interface locals + // These can never be latebound, so the symbol's raw members are sufficient. `getMembersOfNode` cannot be used, as it would + // trigger resolving late-bound names, which we may already be in the process of doing while we're here! + if (result = lookup(getSymbolOfNode(location as ClassLikeDeclaration | InterfaceDeclaration).members || emptySymbols, name, meaning & SymbolFlags.Type)) { if (!isTypeParameterSymbolDeclaredInContainer(result, location)) { // ignore type parameters not declared in this container result = undefined; diff --git a/tests/baselines/reference/declarationTypecheckNoUseBeforeReferenceCheck.symbols b/tests/baselines/reference/declarationTypecheckNoUseBeforeReferenceCheck.symbols new file mode 100644 index 00000000000..95b3bd297c9 --- /dev/null +++ b/tests/baselines/reference/declarationTypecheckNoUseBeforeReferenceCheck.symbols @@ -0,0 +1,14 @@ +=== tests/cases/compiler/index.d.ts === +export class C extends Object { +>C : Symbol(C, Decl(index.d.ts, 0, 0)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + + static readonly p: unique symbol; +>p : Symbol(C.p, Decl(index.d.ts, 0, 31)) + + [C.p](): void; +>[C.p] : Symbol(C[C.p], Decl(index.d.ts, 1, 37)) +>C.p : Symbol(C.p, Decl(index.d.ts, 0, 31)) +>C : Symbol(C, Decl(index.d.ts, 0, 0)) +>p : Symbol(C.p, Decl(index.d.ts, 0, 31)) +} diff --git a/tests/baselines/reference/declarationTypecheckNoUseBeforeReferenceCheck.types b/tests/baselines/reference/declarationTypecheckNoUseBeforeReferenceCheck.types new file mode 100644 index 00000000000..86f294591dc --- /dev/null +++ b/tests/baselines/reference/declarationTypecheckNoUseBeforeReferenceCheck.types @@ -0,0 +1,14 @@ +=== tests/cases/compiler/index.d.ts === +export class C extends Object { +>C : C +>Object : Object + + static readonly p: unique symbol; +>p : unique symbol + + [C.p](): void; +>[C.p] : () => void +>C.p : unique symbol +>C : typeof C +>p : unique symbol +} diff --git a/tests/cases/compiler/declarationTypecheckNoUseBeforeReferenceCheck.ts b/tests/cases/compiler/declarationTypecheckNoUseBeforeReferenceCheck.ts new file mode 100644 index 00000000000..21c1db5f59c --- /dev/null +++ b/tests/cases/compiler/declarationTypecheckNoUseBeforeReferenceCheck.ts @@ -0,0 +1,5 @@ +// @filename: index.d.ts +export class C extends Object { + static readonly p: unique symbol; + [C.p](): void; +} \ No newline at end of file