diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a0675e957ddc8..177c56543ca6b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25809,18 +25809,23 @@ namespace ts { getJsxFactoryEntity: location => location ? (getJsxNamespace(location), (getSourceFileOfNode(location).localJsxFactory || _jsxFactoryEntity)) : _jsxFactoryEntity }; + function isInHeritageClause(node: PropertyAccessEntityNameExpression) { + return node.parent && node.parent.kind === SyntaxKind.ExpressionWithTypeArguments && node.parent.parent && node.parent.parent.kind === SyntaxKind.HeritageClause; + } + // defined here to avoid outer scope pollution function getTypeReferenceDirectivesForEntityName(node: EntityNameOrEntityNameExpression): string[] { // program does not have any files with type reference directives - bail out if (!fileToDirective) { return undefined; } - // property access can only be used as values + // property access can only be used as values, or types when within an expression with type arguments inside a heritage clause // qualified names can only be used as types\namespaces // identifiers are treated as values only if they appear in type queries - const meaning = (node.kind === SyntaxKind.PropertyAccessExpression) || (node.kind === SyntaxKind.Identifier && isInTypeQuery(node)) - ? SymbolFlags.Value | SymbolFlags.ExportValue - : SymbolFlags.Type | SymbolFlags.Namespace; + let meaning = SymbolFlags.Type | SymbolFlags.Namespace; + if ((node.kind === SyntaxKind.Identifier && isInTypeQuery(node)) || (node.kind === SyntaxKind.PropertyAccessExpression && !isInHeritageClause(node))) { + meaning = SymbolFlags.Value | SymbolFlags.ExportValue; + } const symbol = resolveEntityName(node, meaning, /*ignoreErrors*/ true); return symbol && symbol !== unknownSymbol ? getTypeReferenceDirectivesForSymbol(symbol, meaning) : undefined; diff --git a/tests/baselines/reference/declarationEmitHasTypesRefOnNamespaceUse.js b/tests/baselines/reference/declarationEmitHasTypesRefOnNamespaceUse.js new file mode 100644 index 0000000000000..c95366c765fd9 --- /dev/null +++ b/tests/baselines/reference/declarationEmitHasTypesRefOnNamespaceUse.js @@ -0,0 +1,52 @@ +//// [tests/cases/compiler/declarationEmitHasTypesRefOnNamespaceUse.ts] //// + +//// [dep.d.ts] +declare namespace NS { + interface Dep { + } +} +//// [package.json] +{ + "typings": "dep.d.ts" +} +//// [index.ts] +class Src implements NS.Dep { } + + +//// [index.js] +var Src = /** @class */ (function () { + function Src() { + } + return Src; +}()); + + +//// [index.d.ts] +/// +declare class Src implements NS.Dep { +} + + +//// [DtsFileErrors] + + +error TS2688: Cannot find type definition file for 'dep'. +/src/index.d.ts(1,23): error TS2688: Cannot find type definition file for 'dep'. +/src/index.d.ts(2,30): error TS2503: Cannot find namespace 'NS'. + + +!!! error TS2688: Cannot find type definition file for 'dep'. +==== /src/index.d.ts (2 errors) ==== + /// + ~~~ +!!! error TS2688: Cannot find type definition file for 'dep'. + declare class Src implements NS.Dep { + ~~ +!!! error TS2503: Cannot find namespace 'NS'. + } + +==== /deps/dep/dep.d.ts (0 errors) ==== + declare namespace NS { + interface Dep { + } + } \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitHasTypesRefOnNamespaceUse.symbols b/tests/baselines/reference/declarationEmitHasTypesRefOnNamespaceUse.symbols new file mode 100644 index 0000000000000..cecacd3932145 --- /dev/null +++ b/tests/baselines/reference/declarationEmitHasTypesRefOnNamespaceUse.symbols @@ -0,0 +1,15 @@ +=== /src/index.ts === +class Src implements NS.Dep { } +>Src : Symbol(Src, Decl(index.ts, 0, 0)) +>NS.Dep : Symbol(NS.Dep, Decl(dep.d.ts, 0, 22)) +>NS : Symbol(NS, Decl(dep.d.ts, 0, 0)) +>Dep : Symbol(NS.Dep, Decl(dep.d.ts, 0, 22)) + +=== /deps/dep/dep.d.ts === +declare namespace NS { +>NS : Symbol(NS, Decl(dep.d.ts, 0, 0)) + + interface Dep { +>Dep : Symbol(Dep, Decl(dep.d.ts, 0, 22)) + } +} diff --git a/tests/baselines/reference/declarationEmitHasTypesRefOnNamespaceUse.types b/tests/baselines/reference/declarationEmitHasTypesRefOnNamespaceUse.types new file mode 100644 index 0000000000000..33ae73c43d717 --- /dev/null +++ b/tests/baselines/reference/declarationEmitHasTypesRefOnNamespaceUse.types @@ -0,0 +1,15 @@ +=== /src/index.ts === +class Src implements NS.Dep { } +>Src : Src +>NS.Dep : any +>NS : any +>Dep : NS.Dep + +=== /deps/dep/dep.d.ts === +declare namespace NS { +>NS : any + + interface Dep { +>Dep : Dep + } +} diff --git a/tests/cases/compiler/declarationEmitHasTypesRefOnNamespaceUse.ts b/tests/cases/compiler/declarationEmitHasTypesRefOnNamespaceUse.ts new file mode 100644 index 0000000000000..d95fbf3b64db6 --- /dev/null +++ b/tests/cases/compiler/declarationEmitHasTypesRefOnNamespaceUse.ts @@ -0,0 +1,16 @@ +// @declaration: true +// @types: dep +// @typeRoots: /deps +// @currentDirectory: / +// @noImplicitReferences: true +// @filename: /deps/dep/dep.d.ts +declare namespace NS { + interface Dep { + } +} +// @filename: /deps/dep/package.json +{ + "typings": "dep.d.ts" +} +// @filename: /src/index.ts +class Src implements NS.Dep { }