From 1837d0bc19dbcd2fa97c8cdd7d9398a9581a6106 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Fri, 30 Jan 2026 22:49:45 +0100 Subject: [PATCH] Fix incorrectly reported 2689 error --- src/compiler/checker.ts | 4 +-- .../typeUsedAsValueError3.errors.txt | 13 ++++++++++ .../reference/typeUsedAsValueError3.symbols | 18 +++++++++++++ .../reference/typeUsedAsValueError3.types | 25 +++++++++++++++++++ tests/cases/compiler/typeUsedAsValueError3.ts | 9 +++++++ 5 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/typeUsedAsValueError3.errors.txt create mode 100644 tests/baselines/reference/typeUsedAsValueError3.symbols create mode 100644 tests/baselines/reference/typeUsedAsValueError3.types create mode 100644 tests/cases/compiler/typeUsedAsValueError3.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5d446f6799418..5afca2ee873c9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3445,8 +3445,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { case SyntaxKind.PropertyAccessExpression: return node.parent ? getEntityNameForExtendingInterface(node.parent) : undefined; case SyntaxKind.ExpressionWithTypeArguments: - if (isEntityNameExpression((node as ExpressionWithTypeArguments).expression)) { - return (node as ExpressionWithTypeArguments).expression as EntityNameExpression; + if (isExpressionWithTypeArgumentsInClassExtendsClause(node) && isEntityNameExpression(node.expression)) { + return node.expression; } // falls through default: diff --git a/tests/baselines/reference/typeUsedAsValueError3.errors.txt b/tests/baselines/reference/typeUsedAsValueError3.errors.txt new file mode 100644 index 0000000000000..f58ff4b6475e3 --- /dev/null +++ b/tests/baselines/reference/typeUsedAsValueError3.errors.txt @@ -0,0 +1,13 @@ +typeUsedAsValueError3.ts(6,14): error TS2693: 'foo' only refers to a type, but is being used as a value here. + + +==== typeUsedAsValueError3.ts (1 errors) ==== + class baz {} + interface foo { + new (): typeof baz + } + + const bar = (foo) + ~~~ +!!! error TS2693: 'foo' only refers to a type, but is being used as a value here. + \ No newline at end of file diff --git a/tests/baselines/reference/typeUsedAsValueError3.symbols b/tests/baselines/reference/typeUsedAsValueError3.symbols new file mode 100644 index 0000000000000..62349632d5c39 --- /dev/null +++ b/tests/baselines/reference/typeUsedAsValueError3.symbols @@ -0,0 +1,18 @@ +//// [tests/cases/compiler/typeUsedAsValueError3.ts] //// + +=== typeUsedAsValueError3.ts === +class baz {} +>baz : Symbol(baz, Decl(typeUsedAsValueError3.ts, 0, 0)) +>B : Symbol(B, Decl(typeUsedAsValueError3.ts, 0, 10)) + +interface foo { +>foo : Symbol(foo, Decl(typeUsedAsValueError3.ts, 0, 15)) +>A : Symbol(A, Decl(typeUsedAsValueError3.ts, 1, 14)) + + new (): typeof baz +>baz : Symbol(baz, Decl(typeUsedAsValueError3.ts, 0, 0)) +} + +const bar = (foo) +>bar : Symbol(bar, Decl(typeUsedAsValueError3.ts, 5, 5)) + diff --git a/tests/baselines/reference/typeUsedAsValueError3.types b/tests/baselines/reference/typeUsedAsValueError3.types new file mode 100644 index 0000000000000..cb6b5abad2c41 --- /dev/null +++ b/tests/baselines/reference/typeUsedAsValueError3.types @@ -0,0 +1,25 @@ +//// [tests/cases/compiler/typeUsedAsValueError3.ts] //// + +=== typeUsedAsValueError3.ts === +class baz {} +>baz : baz +> : ^^^^^^ + +interface foo { + new (): typeof baz +>baz : typeof baz +> : ^^^^^^^^^^ +} + +const bar = (foo) +>bar : any +> : ^^^ +>(foo) : any +> : ^^^ +>(foo) : any +> : ^^^ +>foo : any +> : ^^^ +>foo : any +> : ^^^ + diff --git a/tests/cases/compiler/typeUsedAsValueError3.ts b/tests/cases/compiler/typeUsedAsValueError3.ts new file mode 100644 index 0000000000000..2f26c9f898791 --- /dev/null +++ b/tests/cases/compiler/typeUsedAsValueError3.ts @@ -0,0 +1,9 @@ +// @strict: true +// @noEmit: true + +class baz {} +interface foo { + new (): typeof baz +} + +const bar = (foo)