Consider property accesses in heritage clauses as type-space references for calculating type reference directives (#22746)

This commit is contained in:
Wesley Wigham 2018-03-29 13:51:52 -07:00 committed by GitHub
parent c861fa9202
commit 3acafe5f42
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 107 additions and 4 deletions

View File

@ -25982,18 +25982,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;

View File

@ -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]
/// <reference types="dep" />
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) ====
/// <reference types="dep" />
~~~
!!! 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 {
}
}

View File

@ -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))
}
}

View File

@ -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
}
}

View File

@ -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 { }