diff --git a/tsc/internal/transformers/declarations/diagnostics.go b/tsc/internal/transformers/declarations/diagnostics.go index 1050afa933eff..9be56fa0a37fb 100644 --- a/tsc/internal/transformers/declarations/diagnostics.go +++ b/tsc/internal/transformers/declarations/diagnostics.go @@ -150,7 +150,10 @@ 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)) { // unique node selection behavior, inline closure return func(symbolAccessibilityResult printer.SymbolAccessibilityResult) *SymbolAccessibilityDiagnostic { var diagnosticMessage *diagnostics.Message diff --git a/tsc/internal/transformers/declarations/util.go b/tsc/internal/transformers/declarations/util.go index 12bfff9600c0d..1f009d21e486c 100644 --- a/tsc/internal/transformers/declarations/util.go +++ b/tsc/internal/transformers/declarations/util.go @@ -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) || diff --git a/tsc/testdata/baselines/reference/compiler/declarationEmitInaccessibleHeritageType.errors.txt b/tsc/testdata/baselines/reference/compiler/declarationEmitInaccessibleHeritageType.errors.txt new file mode 100644 index 0000000000000..76253d8a558fd --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/declarationEmitInaccessibleHeritageType.errors.txt @@ -0,0 +1,53 @@ +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 {} + export interface J extends Base {} + ~ +!!! 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'. + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/declarationEmitInaccessibleHeritageType.js b/tsc/testdata/baselines/reference/compiler/declarationEmitInaccessibleHeritageType.js new file mode 100644 index 0000000000000..64b5720d354cd --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/declarationEmitInaccessibleHeritageType.js @@ -0,0 +1,42 @@ +//// [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 {} +export interface J extends Base {} + +//// [namedClassExpression.ts] +label: interface I {} +export default (class C implements I {}); + +//// [anonymousClassExpression.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 { +}); diff --git a/tsc/testdata/baselines/reference/compiler/declarationEmitInaccessibleHeritageType.symbols b/tsc/testdata/baselines/reference/compiler/declarationEmitInaccessibleHeritageType.symbols new file mode 100644 index 0000000000000..dd5bdd2561567 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/declarationEmitInaccessibleHeritageType.symbols @@ -0,0 +1,46 @@ +//// [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 {} +>Base : Symbol(Base, Decl(typeArgument.ts, 0, 21)) +>T : Symbol(T, Decl(typeArgument.ts, 1, 15)) + +export interface J extends Base {} +>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)) + diff --git a/tsc/testdata/baselines/reference/compiler/declarationEmitInaccessibleHeritageType.types b/tsc/testdata/baselines/reference/compiler/declarationEmitInaccessibleHeritageType.types new file mode 100644 index 0000000000000..d434befb81d68 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/declarationEmitInaccessibleHeritageType.types @@ -0,0 +1,39 @@ +//// [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 {} +export interface J extends Base {} + +=== 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) + diff --git a/tsc/testdata/tests/cases/compiler/declarationEmitInaccessibleHeritageType.ts b/tsc/testdata/tests/cases/compiler/declarationEmitInaccessibleHeritageType.ts new file mode 100644 index 0000000000000..a33322aa8fb58 --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/declarationEmitInaccessibleHeritageType.ts @@ -0,0 +1,22 @@ +// @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 {} +export interface J extends Base {} + +// @filename: namedClassExpression.ts +label: interface I {} +export default (class C implements I {}); + +// @filename: anonymousClassExpression.ts +label: interface I {} +export default (class implements I {});