Skip to content

Commit 3acc76c

Browse files
committed
Allow JS constructor function to return non-void
1 parent 928da67 commit 3acc76c

4 files changed

Lines changed: 160 additions & 1 deletion

File tree

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15835,7 +15835,7 @@ namespace ts {
1583515835
const callSignatures = getSignaturesOfType(expressionType, SignatureKind.Call);
1583615836
if (callSignatures.length) {
1583715837
const signature = resolveCall(node, callSignatures, candidatesOutArray);
15838-
if (getReturnTypeOfSignature(signature) !== voidType) {
15838+
if (!isInJavaScriptFile(signature.declaration) && getReturnTypeOfSignature(signature) !== voidType) {
1583915839
error(node, Diagnostics.Only_a_void_function_can_be_called_with_the_new_keyword);
1584015840
}
1584115841
if (getThisTypeOfSignature(signature) === voidType) {
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
=== tests/cases/compiler/index.js ===
2+
var Person = function (firstNameOrPojo, lastName) {
3+
>Person : Symbol(Person, Decl(index.js, 0, 3))
4+
>firstNameOrPojo : Symbol(firstNameOrPojo, Decl(index.js, 0, 23))
5+
>lastName : Symbol(lastName, Decl(index.js, 0, 39))
6+
7+
if (typeof firstNameOrPojo === "string") {
8+
>firstNameOrPojo : Symbol(firstNameOrPojo, Decl(index.js, 0, 23))
9+
10+
this.firstName = firstNameOrPojo;
11+
>firstName : Symbol(Person.firstName, Decl(index.js, 2, 46))
12+
>firstNameOrPojo : Symbol(firstNameOrPojo, Decl(index.js, 0, 23))
13+
14+
this.lastName = lastName;
15+
>lastName : Symbol(Person.lastName, Decl(index.js, 3, 41))
16+
>lastName : Symbol(lastName, Decl(index.js, 0, 39))
17+
18+
} else {
19+
return new Person(firstNameOrPojo.firstName, firstNameOrPojo.lastName);
20+
>Person : Symbol(Person, Decl(index.js, 0, 3))
21+
>firstNameOrPojo : Symbol(firstNameOrPojo, Decl(index.js, 0, 23))
22+
>firstNameOrPojo : Symbol(firstNameOrPojo, Decl(index.js, 0, 23))
23+
}
24+
};
25+
26+
Person.prototype.greet = function greet() {
27+
>Person.prototype : Symbol(Person.greet, Decl(index.js, 8, 2))
28+
>Person : Symbol(Person, Decl(index.js, 0, 3))
29+
>prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --))
30+
>greet : Symbol(Person.greet, Decl(index.js, 8, 2))
31+
>greet : Symbol(greet, Decl(index.js, 10, 24))
32+
33+
return `Hello, I am ${this.firstName} ${this.lastName}.`;
34+
>this.firstName : Symbol(Person.firstName, Decl(index.js, 2, 46))
35+
>this : Symbol(Person, Decl(index.js, 0, 12))
36+
>firstName : Symbol(Person.firstName, Decl(index.js, 2, 46))
37+
>this.lastName : Symbol(Person.lastName, Decl(index.js, 3, 41))
38+
>this : Symbol(Person, Decl(index.js, 0, 12))
39+
>lastName : Symbol(Person.lastName, Decl(index.js, 3, 41))
40+
41+
};
42+
43+
var fred = new Person({ firstName: "Fred", lastName: "Flintstone" });
44+
>fred : Symbol(fred, Decl(index.js, 14, 3))
45+
>Person : Symbol(Person, Decl(index.js, 0, 3))
46+
>firstName : Symbol(firstName, Decl(index.js, 14, 23))
47+
>lastName : Symbol(lastName, Decl(index.js, 14, 42))
48+
49+
console.log(fred.greet());
50+
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
51+
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
52+
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
53+
>fred.greet : Symbol(Person.greet, Decl(index.js, 8, 2))
54+
>fred : Symbol(fred, Decl(index.js, 14, 3))
55+
>greet : Symbol(Person.greet, Decl(index.js, 8, 2))
56+
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
=== tests/cases/compiler/index.js ===
2+
var Person = function (firstNameOrPojo, lastName) {
3+
>Person : (firstNameOrPojo: any, lastName: any) => any
4+
>function (firstNameOrPojo, lastName) { if (typeof firstNameOrPojo === "string") { this.firstName = firstNameOrPojo; this.lastName = lastName; } else { return new Person(firstNameOrPojo.firstName, firstNameOrPojo.lastName); }} : (firstNameOrPojo: any, lastName: any) => any
5+
>firstNameOrPojo : any
6+
>lastName : any
7+
8+
if (typeof firstNameOrPojo === "string") {
9+
>typeof firstNameOrPojo === "string" : boolean
10+
>typeof firstNameOrPojo : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function"
11+
>firstNameOrPojo : any
12+
>"string" : "string"
13+
14+
this.firstName = firstNameOrPojo;
15+
>this.firstName = firstNameOrPojo : string
16+
>this.firstName : any
17+
>this : any
18+
>firstName : any
19+
>firstNameOrPojo : string
20+
21+
this.lastName = lastName;
22+
>this.lastName = lastName : any
23+
>this.lastName : any
24+
>this : any
25+
>lastName : any
26+
>lastName : any
27+
28+
} else {
29+
return new Person(firstNameOrPojo.firstName, firstNameOrPojo.lastName);
30+
>new Person(firstNameOrPojo.firstName, firstNameOrPojo.lastName) : { firstName: string; lastName: any; greet: () => string; }
31+
>Person : (firstNameOrPojo: any, lastName: any) => any
32+
>firstNameOrPojo.firstName : any
33+
>firstNameOrPojo : any
34+
>firstName : any
35+
>firstNameOrPojo.lastName : any
36+
>firstNameOrPojo : any
37+
>lastName : any
38+
}
39+
};
40+
41+
Person.prototype.greet = function greet() {
42+
>Person.prototype.greet = function greet() { return `Hello, I am ${this.firstName} ${this.lastName}.`;} : () => string
43+
>Person.prototype.greet : any
44+
>Person.prototype : any
45+
>Person : (firstNameOrPojo: any, lastName: any) => any
46+
>prototype : any
47+
>greet : any
48+
>function greet() { return `Hello, I am ${this.firstName} ${this.lastName}.`;} : () => string
49+
>greet : () => string
50+
51+
return `Hello, I am ${this.firstName} ${this.lastName}.`;
52+
>`Hello, I am ${this.firstName} ${this.lastName}.` : string
53+
>this.firstName : string
54+
>this : { firstName: string; lastName: any; greet: () => string; }
55+
>firstName : string
56+
>this.lastName : any
57+
>this : { firstName: string; lastName: any; greet: () => string; }
58+
>lastName : any
59+
60+
};
61+
62+
var fred = new Person({ firstName: "Fred", lastName: "Flintstone" });
63+
>fred : { firstName: string; lastName: any; greet: () => string; }
64+
>new Person({ firstName: "Fred", lastName: "Flintstone" }) : { firstName: string; lastName: any; greet: () => string; }
65+
>Person : (firstNameOrPojo: any, lastName: any) => any
66+
>{ firstName: "Fred", lastName: "Flintstone" } : { firstName: string; lastName: string; }
67+
>firstName : string
68+
>"Fred" : "Fred"
69+
>lastName : string
70+
>"Flintstone" : "Flintstone"
71+
72+
console.log(fred.greet());
73+
>console.log(fred.greet()) : void
74+
>console.log : (message?: any, ...optionalParams: any[]) => void
75+
>console : Console
76+
>log : (message?: any, ...optionalParams: any[]) => void
77+
>fred.greet() : string
78+
>fred.greet : () => string
79+
>fred : { firstName: string; lastName: any; greet: () => string; }
80+
>greet : () => string
81+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// @allowJs: true
2+
// @checkJs: true
3+
// @noEmit: true
4+
// @filename: index.js
5+
// @lib: es5, dom
6+
var Person = function (firstNameOrPojo, lastName) {
7+
8+
if (typeof firstNameOrPojo === "string") {
9+
this.firstName = firstNameOrPojo;
10+
this.lastName = lastName;
11+
} else {
12+
return new Person(firstNameOrPojo.firstName, firstNameOrPojo.lastName);
13+
}
14+
};
15+
16+
Person.prototype.greet = function greet() {
17+
return `Hello, I am ${this.firstName} ${this.lastName}.`;
18+
};
19+
20+
var fred = new Person({ firstName: "Fred", lastName: "Flintstone" });
21+
22+
console.log(fred.greet());

0 commit comments

Comments
 (0)