Skip to content

Commit 1cfab76

Browse files
authored
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 95dc1f2 commit 1cfab76

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
@@ -20284,18 +20284,20 @@ namespace ts {
2028420284
* file.
2028520285
*/
2028620286
function isJSConstructor(node: Declaration | undefined): boolean {
20287-
if (node && isInJSFile(node)) {
20287+
if (!node || !isInJSFile(node)) {
20288+
return false;
20289+
}
20290+
const func = isFunctionDeclaration(node) || isFunctionExpression(node) ? node :
20291+
isVariableDeclaration(node) && node.initializer && isFunctionExpression(node.initializer) ? node.initializer :
20292+
undefined;
20293+
if (func) {
2028820294
// If the node has a @class tag, treat it like a constructor.
2028920295
if (getJSDocClassTag(node)) return true;
2029020296

2029120297
// If the symbol of the node has members, treat it like a constructor.
20292-
const symbol = isFunctionDeclaration(node) || isFunctionExpression(node) ? getSymbolOfNode(node) :
20293-
isVariableDeclaration(node) && node.initializer && isFunctionExpression(node.initializer) ? getSymbolOfNode(node.initializer) :
20294-
undefined;
20295-
20298+
const symbol = getSymbolOfNode(func);
2029620299
return !!symbol && symbol.members !== undefined;
2029720300
}
20298-
2029920301
return false;
2030020302
}
2030120303

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)