Skip to content

Commit b185784

Browse files
committed
Only functions can be constructor functions (#27369)
`@constructor` put on anything incorrectly makes it a JS constructor. This is a problem for actual constructors, because getJSClassType doesn't work on actual classes. The fix is to make isJSConstructor require that its declaration is a function.
1 parent 93b3786 commit b185784

File tree

4 files changed

+61
-6
lines changed

4 files changed

+61
-6
lines changed

src/compiler/checker.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20409,18 +20409,20 @@ namespace ts {
2040920409
* file.
2041020410
*/
2041120411
function isJSConstructor(node: Declaration | undefined): boolean {
20412-
if (node && isInJSFile(node)) {
20412+
if (!node || !isInJSFile(node)) {
20413+
return false;
20414+
}
20415+
const func = isFunctionDeclaration(node) || isFunctionExpression(node) ? node :
20416+
isVariableDeclaration(node) && node.initializer && isFunctionExpression(node.initializer) ? node.initializer :
20417+
undefined;
20418+
if (func) {
2041320419
// If the node has a @class tag, treat it like a constructor.
2041420420
if (getJSDocClassTag(node)) return true;
2041520421

2041620422
// If the symbol of the node has members, treat it like a constructor.
20417-
const symbol = isFunctionDeclaration(node) || isFunctionExpression(node) ? getSymbolOfNode(node) :
20418-
isVariableDeclaration(node) && node.initializer && isFunctionExpression(node.initializer) ? getSymbolOfNode(node.initializer) :
20419-
undefined;
20420-
20423+
const symbol = getSymbolOfNode(func);
2042120424
return !!symbol && symbol.members !== undefined;
2042220425
}
20423-
2042420426
return false;
2042520427
}
2042620428

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
=== tests/cases/conformance/jsdoc/bug27025.js ===
2+
export class Alpha { }
3+
>Alpha : Symbol(Alpha, Decl(bug27025.js, 0, 0))
4+
5+
export class Beta {
6+
>Beta : Symbol(Beta, Decl(bug27025.js, 0, 22))
7+
8+
/**
9+
* @constructor
10+
*/
11+
constructor() {
12+
}
13+
}
14+
15+
const arr = [Alpha, Beta];
16+
>arr : Symbol(arr, Decl(bug27025.js, 9, 5))
17+
>Alpha : Symbol(Alpha, Decl(bug27025.js, 0, 0))
18+
>Beta : Symbol(Beta, Decl(bug27025.js, 0, 22))
19+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
=== tests/cases/conformance/jsdoc/bug27025.js ===
2+
export class Alpha { }
3+
>Alpha : Alpha
4+
5+
export class Beta {
6+
>Beta : Beta
7+
8+
/**
9+
* @constructor
10+
*/
11+
constructor() {
12+
}
13+
}
14+
15+
const arr = [Alpha, Beta];
16+
>arr : (typeof Alpha)[]
17+
>[Alpha, Beta] : (typeof Alpha)[]
18+
>Alpha : typeof Alpha
19+
>Beta : typeof Beta
20+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// @allowJs: true
2+
// @noEmit: true
3+
// @checkJs: true
4+
// @Filename: bug27025.js
5+
export class Alpha { }
6+
export class Beta {
7+
/**
8+
* @constructor
9+
*/
10+
constructor() {
11+
}
12+
}
13+
14+
const arr = [Alpha, Beta];

0 commit comments

Comments
 (0)