Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions tsc/internal/transformers/declarations/diagnostics.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,15 +150,22 @@ func createGetSymbolAccessibilityDiagnosticForNode(node *ast.Node) GetSymbolAcce
return wrapSimpleDiagnosticSelector(node, getParameterDeclarationTypeVisibilityDiagnosticMessage)
} else if ast.IsTypeParameterDeclaration(node) {
return wrapSimpleDiagnosticSelector(node, getTypeParameterConstraintVisibilityDiagnosticMessage)
} else if ast.IsExpressionWithTypeArguments(node) {
} else if ast.IsExpressionWithTypeArguments(node) ||
(ast.IsTypeReferenceNode(node) &&
ast.IsHeritageClause(node.Parent) &&
!ast.IsClassExpression(node.Parent.Parent)) {
Comment thread
chengchuu marked this conversation as resolved.
Resolved
// unique node selection behavior, inline closure
return func(symbolAccessibilityResult printer.SymbolAccessibilityResult) *SymbolAccessibilityDiagnostic {
var diagnosticMessage *diagnostics.Message
// Heritage clause is written by user so it can always be named
if ast.IsClassDeclaration(node.Parent.Parent) {
// Class or Interface implemented/extended is inaccessible
if ast.IsHeritageClause(node.Parent) && node.Parent.AsHeritageClause().Token == ast.KindImplementsKeyword {
diagnosticMessage = diagnostics.Implements_clause_of_exported_class_0_has_or_is_using_private_name_1
if node.Parent.Parent.Name() != nil {
diagnosticMessage = diagnostics.Implements_clause_of_exported_class_0_has_or_is_using_private_name_1
} else {
diagnosticMessage = diagnostics.Default_export_of_the_module_has_or_is_using_private_name_0
}
} else {
if node.Parent.Parent.Name() != nil {
diagnosticMessage = diagnostics.X_extends_clause_of_exported_class_0_has_or_is_using_private_name_1
Expand Down
3 changes: 3 additions & 0 deletions tsc/internal/transformers/declarations/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ func canProduceDiagnostics(node *ast.Node) bool {
ast.IsParameterDeclaration(node) ||
ast.IsTypeParameterDeclaration(node) ||
ast.IsExpressionWithTypeArguments(node) ||
(ast.IsTypeReferenceNode(node) &&
ast.IsHeritageClause(node.Parent) &&
!ast.IsClassExpression(node.Parent.Parent)) ||
ast.IsImportEqualsDeclaration(node) ||
ast.IsTypeAliasDeclaration(node) ||
ast.IsJSTypeAliasDeclaration(node) ||
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
anonymousClassDeclaration.ts(1,1): error TS1344: A label is not allowed here.
anonymousClassDeclaration.ts(2,33): error TS4082: Default export of the module has or is using private name 'I'.
anonymousClassExpression.ts(1,1): error TS1344: A label is not allowed here.
anonymousClassExpression.ts(2,34): error TS4082: Default export of the module has or is using private name 'I'.
implements.ts(1,1): error TS1344: A label is not allowed here.
implements.ts(2,27): error TS4019: Implements clause of exported class 'C' has or is using private name 'I'.
interface.ts(1,1): error TS1344: A label is not allowed here.
interface.ts(2,28): error TS4022: 'extends' clause of exported interface 'J' has or is using private name 'I'.
namedClassExpression.ts(1,1): error TS1344: A label is not allowed here.
namedClassExpression.ts(2,36): error TS4082: Default export of the module has or is using private name 'I'.
typeArgument.ts(1,1): error TS1344: A label is not allowed here.
typeArgument.ts(3,33): error TS4022: 'extends' clause of exported interface 'J' has or is using private name 'I'.


==== interface.ts (2 errors) ====
label: interface I {}
~~~~~
!!! error TS1344: A label is not allowed here.
export interface J extends I {}
~
!!! error TS4022: 'extends' clause of exported interface 'J' has or is using private name 'I'.

==== implements.ts (2 errors) ====
label: interface I {}
~~~~~
!!! error TS1344: A label is not allowed here.
export class C implements I {}
~
!!! error TS4019: Implements clause of exported class 'C' has or is using private name 'I'.

==== typeArgument.ts (2 errors) ====
label: interface I {}
~~~~~
!!! error TS1344: A label is not allowed here.
interface Base<T> {}
export interface J extends Base<I> {}
~
!!! error TS4022: 'extends' clause of exported interface 'J' has or is using private name 'I'.

==== namedClassExpression.ts (2 errors) ====
label: interface I {}
~~~~~
!!! error TS1344: A label is not allowed here.
export default (class C implements I {});
~
!!! error TS4082: Default export of the module has or is using private name 'I'.

==== anonymousClassExpression.ts (2 errors) ====
label: interface I {}
~~~~~
!!! error TS1344: A label is not allowed here.
export default (class implements I {});
~
!!! error TS4082: Default export of the module has or is using private name 'I'.

==== anonymousClassDeclaration.ts (2 errors) ====
label: interface I {}
~~~~~
!!! error TS1344: A label is not allowed here.
export default class implements I {}
~
!!! error TS4082: Default export of the module has or is using private name 'I'.

Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//// [tests/cases/compiler/declarationEmitInaccessibleHeritageType.ts] ////

//// [interface.ts]
label: interface I {}
export interface J extends I {}

//// [implements.ts]
label: interface I {}
export class C implements I {}

//// [typeArgument.ts]
label: interface I {}
interface Base<T> {}
export interface J extends Base<I> {}

//// [namedClassExpression.ts]
label: interface I {}
export default (class C implements I {});

//// [anonymousClassExpression.ts]
label: interface I {}
export default (class implements I {});

//// [anonymousClassDeclaration.ts]
label: interface I {}
export default class implements I {}


//// [interface.js]
label: ;
export {};
//// [implements.js]
label: ;
export class C {
}
//// [typeArgument.js]
label: ;
export {};
//// [namedClassExpression.js]
label: ;
export default (class C {
});
//// [anonymousClassExpression.js]
label: ;
export default (class {
});
//// [anonymousClassDeclaration.js]
label: ;
export default class {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//// [tests/cases/compiler/declarationEmitInaccessibleHeritageType.ts] ////

=== interface.ts ===
label: interface I {}
>I : Symbol(I, Decl(interface.ts, 0, 6))

export interface J extends I {}
>J : Symbol(J, Decl(interface.ts, 0, 21))
>I : Symbol(I, Decl(interface.ts, 0, 6))

=== implements.ts ===
label: interface I {}
>I : Symbol(I, Decl(implements.ts, 0, 6))

export class C implements I {}
>C : Symbol(C, Decl(implements.ts, 0, 21))
>I : Symbol(I, Decl(implements.ts, 0, 6))

=== typeArgument.ts ===
label: interface I {}
>I : Symbol(I, Decl(typeArgument.ts, 0, 6))

interface Base<T> {}
>Base : Symbol(Base, Decl(typeArgument.ts, 0, 21))
>T : Symbol(T, Decl(typeArgument.ts, 1, 15))

export interface J extends Base<I> {}
>J : Symbol(J, Decl(typeArgument.ts, 1, 20))
>Base : Symbol(Base, Decl(typeArgument.ts, 0, 21))
>I : Symbol(I, Decl(typeArgument.ts, 0, 6))

=== namedClassExpression.ts ===
label: interface I {}
>I : Symbol(I, Decl(namedClassExpression.ts, 0, 6))

export default (class C implements I {});
>C : Symbol(C, Decl(namedClassExpression.ts, 1, 16))
>I : Symbol(I, Decl(namedClassExpression.ts, 0, 6))

=== anonymousClassExpression.ts ===
label: interface I {}
>I : Symbol(I, Decl(anonymousClassExpression.ts, 0, 6))

export default (class implements I {});
>I : Symbol(I, Decl(anonymousClassExpression.ts, 0, 6))

=== anonymousClassDeclaration.ts ===
label: interface I {}
>I : Symbol(I, Decl(anonymousClassDeclaration.ts, 0, 6))

export default class implements I {}
>I : Symbol(I, Decl(anonymousClassDeclaration.ts, 0, 6))

Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//// [tests/cases/compiler/declarationEmitInaccessibleHeritageType.ts] ////

=== interface.ts ===
label: interface I {}
>label : any

export interface J extends I {}

=== implements.ts ===
label: interface I {}
>label : any

export class C implements I {}
>C : C

=== typeArgument.ts ===
label: interface I {}
>label : any

interface Base<T> {}
export interface J extends Base<I> {}

=== namedClassExpression.ts ===
label: interface I {}
>label : any

export default (class C implements I {});
>(class C implements I {}) : typeof C
>class C implements I {} : typeof C
>C : typeof C

=== anonymousClassExpression.ts ===
label: interface I {}
>label : any

export default (class implements I {});
>(class implements I {}) : typeof (Anonymous class)
>class implements I {} : typeof (Anonymous class)

=== anonymousClassDeclaration.ts ===
label: interface I {}
>label : any

export default class implements I {}

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// @declaration: true

// @filename: interface.ts
label: interface I {}
export interface J extends I {}

// @filename: implements.ts
label: interface I {}
export class C implements I {}

// @filename: typeArgument.ts
label: interface I {}
interface Base<T> {}
export interface J extends Base<I> {}

// @filename: namedClassExpression.ts
label: interface I {}
export default (class C implements I {});

// @filename: anonymousClassExpression.ts
label: interface I {}
export default (class implements I {});

// @filename: anonymousClassDeclaration.ts
label: interface I {}
export default class implements I {}