Skip to content

Commit 75071a2

Browse files
authored
Allow super references to constructor function methods (#26482)
Previously, they were mistakenly treated as private because of a check that required all super property accesses (like `super.x()`) to be references to a MethodDeclaration or MethodSignature. This change also allows PrototypeProperty special assignment kinds.
1 parent 56f8256 commit 75071a2

File tree

4 files changed

+135
-19
lines changed

4 files changed

+135
-19
lines changed

tests/baselines/reference/classCanExtendConstructorFunction.errors.txt

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
tests/cases/conformance/salsa/first.js(18,9): error TS2554: Expected 1 arguments, but got 0.
2-
tests/cases/conformance/salsa/first.js(26,5): error TS2416: Property 'load' in type 'Sql' is not assignable to the same property in base type 'Wagon'.
1+
tests/cases/conformance/salsa/first.js(23,9): error TS2554: Expected 1 arguments, but got 0.
2+
tests/cases/conformance/salsa/first.js(31,5): error TS2416: Property 'load' in type 'Sql' is not assignable to the same property in base type 'Wagon'.
33
Type '(files: string[], format: "csv" | "json" | "xmlolololol") => void' is not assignable to type '(supplies?: any[]) => void'.
4-
tests/cases/conformance/salsa/first.js(36,24): error TS2507: Type '(numberEaten: number) => void' is not a constructor function type.
4+
tests/cases/conformance/salsa/first.js(47,24): error TS2507: Type '(numberEaten: number) => void' is not a constructor function type.
55
tests/cases/conformance/salsa/generic.js(8,15): error TS2508: No base constructor has the specified number of type arguments.
66
tests/cases/conformance/salsa/generic.js(11,21): error TS2339: Property 'flavour' does not exist on type 'Chowder'.
77
tests/cases/conformance/salsa/generic.js(18,9): error TS2339: Property 'flavour' does not exist on type 'Chowder'.
@@ -31,6 +31,11 @@ tests/cases/conformance/salsa/second.ts(17,15): error TS2345: Argument of type '
3131
/** @param {*[]=} supplies - *[]= is my favourite type */
3232
Wagon.prototype.load = function (supplies) {
3333
}
34+
/** @param {*[]=} supplies - Yep, still a great type */
35+
Wagon.prototype.weight = supplies => supplies ? supplies.length : -1
36+
Wagon.prototype.speed = function () {
37+
return this.numberOxen / this.weight()
38+
}
3439
// ok
3540
class Sql extends Wagon {
3641
constructor() {
@@ -51,6 +56,12 @@ tests/cases/conformance/salsa/second.ts(17,15): error TS2345: Argument of type '
5156
if (format === "xmlolololol") {
5257
throw new Error("please do not use XML. It was a joke.");
5358
}
59+
else {
60+
super.speed() // run faster
61+
if (super.weight() < 0) {
62+
// ????????????????????????
63+
}
64+
}
5465
}
5566
}
5667
var db = new Sql();

tests/baselines/reference/classCanExtendConstructorFunction.symbols

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,53 +34,93 @@ Wagon.prototype.load = function (supplies) {
3434
>load : Symbol(Wagon.load, Decl(first.js, 10, 1))
3535
>supplies : Symbol(supplies, Decl(first.js, 12, 33))
3636
}
37+
/** @param {*[]=} supplies - Yep, still a great type */
38+
Wagon.prototype.weight = supplies => supplies ? supplies.length : -1
39+
>Wagon.prototype : Symbol(Wagon.weight, Decl(first.js, 13, 1))
40+
>Wagon : Symbol(Wagon, Decl(first.js, 0, 0), Decl(first.js, 6, 1))
41+
>prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --))
42+
>weight : Symbol(Wagon.weight, Decl(first.js, 13, 1))
43+
>supplies : Symbol(supplies, Decl(first.js, 15, 24))
44+
>supplies : Symbol(supplies, Decl(first.js, 15, 24))
45+
>supplies.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
46+
>supplies : Symbol(supplies, Decl(first.js, 15, 24))
47+
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
48+
49+
Wagon.prototype.speed = function () {
50+
>Wagon.prototype : Symbol(Wagon.speed, Decl(first.js, 15, 68))
51+
>Wagon : Symbol(Wagon, Decl(first.js, 0, 0), Decl(first.js, 6, 1))
52+
>prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --))
53+
>speed : Symbol(Wagon.speed, Decl(first.js, 15, 68))
54+
55+
return this.numberOxen / this.weight()
56+
>this.numberOxen : Symbol(Wagon.numberOxen, Decl(first.js, 4, 28))
57+
>this : Symbol(Wagon, Decl(first.js, 0, 0), Decl(first.js, 6, 1))
58+
>numberOxen : Symbol(Wagon.numberOxen, Decl(first.js, 4, 28))
59+
>this.weight : Symbol(Wagon.weight, Decl(first.js, 13, 1))
60+
>this : Symbol(Wagon, Decl(first.js, 0, 0), Decl(first.js, 6, 1))
61+
>weight : Symbol(Wagon.weight, Decl(first.js, 13, 1))
62+
}
3763
// ok
3864
class Sql extends Wagon {
39-
>Sql : Symbol(Sql, Decl(first.js, 13, 1))
65+
>Sql : Symbol(Sql, Decl(first.js, 18, 1))
4066
>Wagon : Symbol(Wagon, Decl(first.js, 0, 0), Decl(first.js, 6, 1))
4167

4268
constructor() {
4369
super(); // error: not enough arguments
4470
>super : Symbol(Wagon, Decl(first.js, 0, 0), Decl(first.js, 6, 1))
4571

4672
this.foonly = 12
47-
>this.foonly : Symbol(Sql.foonly, Decl(first.js, 17, 16))
48-
>this : Symbol(Sql, Decl(first.js, 13, 1))
49-
>foonly : Symbol(Sql.foonly, Decl(first.js, 17, 16))
73+
>this.foonly : Symbol(Sql.foonly, Decl(first.js, 22, 16))
74+
>this : Symbol(Sql, Decl(first.js, 18, 1))
75+
>foonly : Symbol(Sql.foonly, Decl(first.js, 22, 16))
5076
}
5177
/**
5278
* @param {Array.<string>} files
5379
* @param {"csv" | "json" | "xmlolololol"} format
5480
* This is not assignable, so should have a type error
5581
*/
5682
load(files, format) {
57-
>load : Symbol(Sql.load, Decl(first.js, 19, 5))
58-
>files : Symbol(files, Decl(first.js, 25, 9))
59-
>format : Symbol(format, Decl(first.js, 25, 15))
83+
>load : Symbol(Sql.load, Decl(first.js, 24, 5))
84+
>files : Symbol(files, Decl(first.js, 30, 9))
85+
>format : Symbol(format, Decl(first.js, 30, 15))
6086

6187
if (format === "xmlolololol") {
62-
>format : Symbol(format, Decl(first.js, 25, 15))
88+
>format : Symbol(format, Decl(first.js, 30, 15))
6389

6490
throw new Error("please do not use XML. It was a joke.");
6591
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
6692
}
93+
else {
94+
super.speed() // run faster
95+
>super.speed : Symbol(Wagon.speed, Decl(first.js, 15, 68))
96+
>super : Symbol(Wagon, Decl(first.js, 0, 0), Decl(first.js, 6, 1))
97+
>speed : Symbol(Wagon.speed, Decl(first.js, 15, 68))
98+
99+
if (super.weight() < 0) {
100+
>super.weight : Symbol(Wagon.weight, Decl(first.js, 13, 1))
101+
>super : Symbol(Wagon, Decl(first.js, 0, 0), Decl(first.js, 6, 1))
102+
>weight : Symbol(Wagon.weight, Decl(first.js, 13, 1))
103+
104+
// ????????????????????????
105+
}
106+
}
67107
}
68108
}
69109
var db = new Sql();
70-
>db : Symbol(db, Decl(first.js, 31, 3))
71-
>Sql : Symbol(Sql, Decl(first.js, 13, 1))
110+
>db : Symbol(db, Decl(first.js, 42, 3))
111+
>Sql : Symbol(Sql, Decl(first.js, 18, 1))
72112

73113
db.numberOxen = db.foonly
74114
>db.numberOxen : Symbol(Wagon.numberOxen, Decl(first.js, 4, 28))
75-
>db : Symbol(db, Decl(first.js, 31, 3))
115+
>db : Symbol(db, Decl(first.js, 42, 3))
76116
>numberOxen : Symbol(Wagon.numberOxen, Decl(first.js, 4, 28))
77-
>db.foonly : Symbol(Sql.foonly, Decl(first.js, 17, 16))
78-
>db : Symbol(db, Decl(first.js, 31, 3))
79-
>foonly : Symbol(Sql.foonly, Decl(first.js, 17, 16))
117+
>db.foonly : Symbol(Sql.foonly, Decl(first.js, 22, 16))
118+
>db : Symbol(db, Decl(first.js, 42, 3))
119+
>foonly : Symbol(Sql.foonly, Decl(first.js, 22, 16))
80120

81121
// error, can't extend a TS constructor function
82122
class Drakkhen extends Dragon {
83-
>Drakkhen : Symbol(Drakkhen, Decl(first.js, 32, 25))
123+
>Drakkhen : Symbol(Drakkhen, Decl(first.js, 43, 25))
84124
>Dragon : Symbol(Dragon, Decl(second.ts, 0, 0))
85125

86126
}

tests/baselines/reference/classCanExtendConstructorFunction.types

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,43 @@ Wagon.prototype.load = function (supplies) {
4242
>function (supplies) {} : (supplies?: any[]) => void
4343
>supplies : any[]
4444
}
45+
/** @param {*[]=} supplies - Yep, still a great type */
46+
Wagon.prototype.weight = supplies => supplies ? supplies.length : -1
47+
>Wagon.prototype.weight = supplies => supplies ? supplies.length : -1 : (supplies?: any[]) => number
48+
>Wagon.prototype.weight : any
49+
>Wagon.prototype : any
50+
>Wagon : typeof Wagon
51+
>prototype : any
52+
>weight : any
53+
>supplies => supplies ? supplies.length : -1 : (supplies?: any[]) => number
54+
>supplies : any[]
55+
>supplies ? supplies.length : -1 : number
56+
>supplies : any[]
57+
>supplies.length : number
58+
>supplies : any[]
59+
>length : number
60+
>-1 : -1
61+
>1 : 1
62+
63+
Wagon.prototype.speed = function () {
64+
>Wagon.prototype.speed = function () { return this.numberOxen / this.weight()} : () => number
65+
>Wagon.prototype.speed : any
66+
>Wagon.prototype : any
67+
>Wagon : typeof Wagon
68+
>prototype : any
69+
>speed : any
70+
>function () { return this.numberOxen / this.weight()} : () => number
71+
72+
return this.numberOxen / this.weight()
73+
>this.numberOxen / this.weight() : number
74+
>this.numberOxen : number
75+
>this : Wagon
76+
>numberOxen : number
77+
>this.weight() : number
78+
>this.weight : (supplies?: any[]) => number
79+
>this : Wagon
80+
>weight : (supplies?: any[]) => number
81+
}
4582
// ok
4683
class Sql extends Wagon {
4784
>Sql : Sql
@@ -79,6 +116,24 @@ class Sql extends Wagon {
79116
>Error : ErrorConstructor
80117
>"please do not use XML. It was a joke." : "please do not use XML. It was a joke."
81118
}
119+
else {
120+
super.speed() // run faster
121+
>super.speed() : number
122+
>super.speed : () => number
123+
>super : Wagon
124+
>speed : () => number
125+
126+
if (super.weight() < 0) {
127+
>super.weight() < 0 : boolean
128+
>super.weight() : number
129+
>super.weight : (supplies?: any[]) => number
130+
>super : Wagon
131+
>weight : (supplies?: any[]) => number
132+
>0 : 0
133+
134+
// ????????????????????????
135+
}
136+
}
82137
}
83138
}
84139
var db = new Sql();

tests/cases/conformance/salsa/classCanExtendConstructorFunction.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// @allowJs: true
33
// @checkJs: true
44
// @Filename: first.js
5-
65
/**
76
* @constructor
87
* @param {number} numberOxen
@@ -17,6 +16,11 @@ Wagon.circle = function (wagons) {
1716
/** @param {*[]=} supplies - *[]= is my favourite type */
1817
Wagon.prototype.load = function (supplies) {
1918
}
19+
/** @param {*[]=} supplies - Yep, still a great type */
20+
Wagon.prototype.weight = supplies => supplies ? supplies.length : -1
21+
Wagon.prototype.speed = function () {
22+
return this.numberOxen / this.weight()
23+
}
2024
// ok
2125
class Sql extends Wagon {
2226
constructor() {
@@ -32,6 +36,12 @@ class Sql extends Wagon {
3236
if (format === "xmlolololol") {
3337
throw new Error("please do not use XML. It was a joke.");
3438
}
39+
else {
40+
super.speed() // run faster
41+
if (super.weight() < 0) {
42+
// ????????????????????????
43+
}
44+
}
3545
}
3646
}
3747
var db = new Sql();

0 commit comments

Comments
 (0)