Fix longer type-only property access in non-emitting heritage clauses (#37264)
* Fix longer type-only property access in non-emitting heritage clauses * Rename misnomer function
This commit is contained in:
parent
8d63a7a842
commit
bc0e5a241c
|
@ -6267,7 +6267,7 @@ namespace ts {
|
|||
export function isValidTypeOnlyAliasUseSite(useSite: Node): boolean {
|
||||
return !!(useSite.flags & NodeFlags.Ambient)
|
||||
|| isPartOfTypeQuery(useSite)
|
||||
|| isFirstIdentifierOfNonEmittingHeritageClause(useSite)
|
||||
|| isIdentifierInNonEmittingHeritageClause(useSite)
|
||||
|| isPartOfPossiblyValidTypeOrAbstractComputedPropertyName(useSite)
|
||||
|| !isExpressionNode(useSite);
|
||||
}
|
||||
|
@ -6290,10 +6290,20 @@ namespace ts {
|
|||
return containerKind === SyntaxKind.InterfaceDeclaration || containerKind === SyntaxKind.TypeLiteral;
|
||||
}
|
||||
|
||||
/** Returns true for the first identifier of 1) an `implements` clause, and 2) an `extends` clause of an interface. */
|
||||
function isFirstIdentifierOfNonEmittingHeritageClause(node: Node): boolean {
|
||||
// Number of parents to climb from identifier is 2 for `implements I`, 3 for `implements x.I`
|
||||
const heritageClause = tryCast(node.parent.parent, isHeritageClause) ?? tryCast(node.parent.parent?.parent, isHeritageClause);
|
||||
/** Returns true for an identifier in 1) an `implements` clause, and 2) an `extends` clause of an interface. */
|
||||
function isIdentifierInNonEmittingHeritageClause(node: Node): boolean {
|
||||
if (node.kind !== SyntaxKind.Identifier) return false;
|
||||
const heritageClause = findAncestor(node.parent, parent => {
|
||||
switch (parent.kind) {
|
||||
case SyntaxKind.HeritageClause:
|
||||
return true;
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
return false;
|
||||
default:
|
||||
return "quit";
|
||||
}
|
||||
}) as HeritageClause | undefined;
|
||||
return heritageClause?.token === SyntaxKind.ImplementsKeyword || heritageClause?.parent.kind === SyntaxKind.InterfaceDeclaration;
|
||||
}
|
||||
}
|
||||
|
|
28
tests/baselines/reference/nestedNamespace.js
Normal file
28
tests/baselines/reference/nestedNamespace.js
Normal file
|
@ -0,0 +1,28 @@
|
|||
//// [tests/cases/conformance/externalModules/typeOnly/nestedNamespace.ts] ////
|
||||
|
||||
//// [a.ts]
|
||||
export namespace types {
|
||||
export class A {}
|
||||
}
|
||||
|
||||
//// [b.ts]
|
||||
import type * as a from './a';
|
||||
interface B extends a.types.A {}
|
||||
|
||||
|
||||
//// [a.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.types = void 0;
|
||||
var types;
|
||||
(function (types) {
|
||||
var A = /** @class */ (function () {
|
||||
function A() {
|
||||
}
|
||||
return A;
|
||||
}());
|
||||
types.A = A;
|
||||
})(types = exports.types || (exports.types = {}));
|
||||
//// [b.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
20
tests/baselines/reference/nestedNamespace.symbols
Normal file
20
tests/baselines/reference/nestedNamespace.symbols
Normal file
|
@ -0,0 +1,20 @@
|
|||
=== tests/cases/conformance/externalModules/typeOnly/a.ts ===
|
||||
export namespace types {
|
||||
>types : Symbol(types, Decl(a.ts, 0, 0))
|
||||
|
||||
export class A {}
|
||||
>A : Symbol(A, Decl(a.ts, 0, 24))
|
||||
}
|
||||
|
||||
=== tests/cases/conformance/externalModules/typeOnly/b.ts ===
|
||||
import type * as a from './a';
|
||||
>a : Symbol(a, Decl(b.ts, 0, 11))
|
||||
|
||||
interface B extends a.types.A {}
|
||||
>B : Symbol(B, Decl(b.ts, 0, 30))
|
||||
>a.types.A : Symbol(a.types.A, Decl(a.ts, 0, 24))
|
||||
>a.types : Symbol(a.types, Decl(a.ts, 0, 0))
|
||||
>a : Symbol(a, Decl(b.ts, 0, 11))
|
||||
>types : Symbol(a.types, Decl(a.ts, 0, 0))
|
||||
>A : Symbol(a.types.A, Decl(a.ts, 0, 24))
|
||||
|
17
tests/baselines/reference/nestedNamespace.types
Normal file
17
tests/baselines/reference/nestedNamespace.types
Normal file
|
@ -0,0 +1,17 @@
|
|||
=== tests/cases/conformance/externalModules/typeOnly/a.ts ===
|
||||
export namespace types {
|
||||
>types : typeof types
|
||||
|
||||
export class A {}
|
||||
>A : A
|
||||
}
|
||||
|
||||
=== tests/cases/conformance/externalModules/typeOnly/b.ts ===
|
||||
import type * as a from './a';
|
||||
>a : typeof a
|
||||
|
||||
interface B extends a.types.A {}
|
||||
>a.types : typeof a.types
|
||||
>a : typeof a
|
||||
>types : typeof a.types
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
// @Filename: a.ts
|
||||
export namespace types {
|
||||
export class A {}
|
||||
}
|
||||
|
||||
// @Filename: b.ts
|
||||
import type * as a from './a';
|
||||
interface B extends a.types.A {}
|
Loading…
Reference in a new issue