Skip to content

Commit 2669ce7

Browse files
committed
Fix longer type-only property access in non-emitting heritage clauses
1 parent 631def8 commit 2669ce7

File tree

5 files changed

+85
-2
lines changed

5 files changed

+85
-2
lines changed

src/compiler/utilities.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6292,8 +6292,18 @@ namespace ts {
62926292

62936293
/** Returns true for the first identifier of 1) an `implements` clause, and 2) an `extends` clause of an interface. */
62946294
function isFirstIdentifierOfNonEmittingHeritageClause(node: Node): boolean {
6295-
// Number of parents to climb from identifier is 2 for `implements I`, 3 for `implements x.I`
6296-
const heritageClause = tryCast(node.parent.parent, isHeritageClause) ?? tryCast(node.parent.parent?.parent, isHeritageClause);
6295+
if (node.kind !== SyntaxKind.Identifier) return false;
6296+
const heritageClause = findAncestor(node.parent, parent => {
6297+
switch (parent.kind) {
6298+
case SyntaxKind.HeritageClause:
6299+
return true;
6300+
case SyntaxKind.PropertyAccessExpression:
6301+
case SyntaxKind.ExpressionWithTypeArguments:
6302+
return false;
6303+
default:
6304+
return "quit";
6305+
}
6306+
}) as HeritageClause | undefined;
62976307
return heritageClause?.token === SyntaxKind.ImplementsKeyword || heritageClause?.parent.kind === SyntaxKind.InterfaceDeclaration;
62986308
}
62996309
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//// [tests/cases/conformance/externalModules/typeOnly/nestedNamespace.ts] ////
2+
3+
//// [a.ts]
4+
export namespace types {
5+
export class A {}
6+
}
7+
8+
//// [b.ts]
9+
import type * as a from './a';
10+
interface B extends a.types.A {}
11+
12+
13+
//// [a.js]
14+
"use strict";
15+
exports.__esModule = true;
16+
exports.types = void 0;
17+
var types;
18+
(function (types) {
19+
var A = /** @class */ (function () {
20+
function A() {
21+
}
22+
return A;
23+
}());
24+
types.A = A;
25+
})(types = exports.types || (exports.types = {}));
26+
//// [b.js]
27+
"use strict";
28+
exports.__esModule = true;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
=== tests/cases/conformance/externalModules/typeOnly/a.ts ===
2+
export namespace types {
3+
>types : Symbol(types, Decl(a.ts, 0, 0))
4+
5+
export class A {}
6+
>A : Symbol(A, Decl(a.ts, 0, 24))
7+
}
8+
9+
=== tests/cases/conformance/externalModules/typeOnly/b.ts ===
10+
import type * as a from './a';
11+
>a : Symbol(a, Decl(b.ts, 0, 11))
12+
13+
interface B extends a.types.A {}
14+
>B : Symbol(B, Decl(b.ts, 0, 30))
15+
>a.types.A : Symbol(a.types.A, Decl(a.ts, 0, 24))
16+
>a.types : Symbol(a.types, Decl(a.ts, 0, 0))
17+
>a : Symbol(a, Decl(b.ts, 0, 11))
18+
>types : Symbol(a.types, Decl(a.ts, 0, 0))
19+
>A : Symbol(a.types.A, Decl(a.ts, 0, 24))
20+
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
=== tests/cases/conformance/externalModules/typeOnly/a.ts ===
2+
export namespace types {
3+
>types : typeof types
4+
5+
export class A {}
6+
>A : A
7+
}
8+
9+
=== tests/cases/conformance/externalModules/typeOnly/b.ts ===
10+
import type * as a from './a';
11+
>a : typeof a
12+
13+
interface B extends a.types.A {}
14+
>a.types : typeof a.types
15+
>a : typeof a
16+
>types : typeof a.types
17+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// @Filename: a.ts
2+
export namespace types {
3+
export class A {}
4+
}
5+
6+
// @Filename: b.ts
7+
import type * as a from './a';
8+
interface B extends a.types.A {}

0 commit comments

Comments
 (0)