Skip to content

Commit 791c747

Browse files
authored
Allow override as parameter property (#43831)
* Allow `override` as parameter property * Update other baseline * Add test for override on normal parameter * Copy typo fix * Update baselines * Update API baseline
1 parent db09cb5 commit 791c747

11 files changed

+283
-11
lines changed

src/compiler/checker.ts

+2-4
Original file line numberDiff line numberDiff line change
@@ -40666,6 +40666,7 @@ namespace ts {
4066640666
}
4066740667
break;
4066840668
case SyntaxKind.OverrideKeyword:
40669+
// If node.kind === SyntaxKind.Parameter, checkParameter reports an error if it's not a parameter property.
4066940670
if (flags & ModifierFlags.Override) {
4067040671
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "override");
4067140672
}
@@ -40678,9 +40679,6 @@ namespace ts {
4067840679
else if (flags & ModifierFlags.Async) {
4067940680
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "override", "async");
4068040681
}
40681-
if (node.kind === SyntaxKind.Parameter) {
40682-
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_parameter, "override");
40683-
}
4068440682
flags |= ModifierFlags.Override;
4068540683
lastOverride = modifier;
4068640684
break;
@@ -40753,7 +40751,7 @@ namespace ts {
4075340751
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "readonly");
4075440752
}
4075540753
else if (node.kind !== SyntaxKind.PropertyDeclaration && node.kind !== SyntaxKind.PropertySignature && node.kind !== SyntaxKind.IndexSignature && node.kind !== SyntaxKind.Parameter) {
40756-
// If node.kind === SyntaxKind.Parameter, checkParameter report an error if it's not a parameter property.
40754+
// If node.kind === SyntaxKind.Parameter, checkParameter reports an error if it's not a parameter property.
4075740755
return grammarErrorOnNode(modifier, Diagnostics.readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature);
4075840756
}
4075940757
flags |= ModifierFlags.Readonly;

src/compiler/types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -806,7 +806,7 @@ namespace ts {
806806

807807
AccessibilityModifier = Public | Private | Protected,
808808
// Accessibility modifiers and 'readonly' can be attached to a parameter in a constructor to make it a property.
809-
ParameterPropertyModifier = AccessibilityModifier | Readonly,
809+
ParameterPropertyModifier = AccessibilityModifier | Readonly | Override,
810810
NonPublicAccessibilityModifier = Private | Protected,
811811

812812
TypeScriptModifier = Ambient | Public | Private | Protected | Readonly | Abstract | Const | Override,

src/harness/fourslashInterfaceImpl.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1175,7 +1175,7 @@ namespace FourSlashInterface {
11751175
export const classElementInJsKeywords = getInJsKeywords(classElementKeywords);
11761176

11771177
export const constructorParameterKeywords: readonly ExpectedCompletionEntryObject[] =
1178-
["private", "protected", "public", "readonly"].map((name): ExpectedCompletionEntryObject => ({
1178+
["private", "protected", "public", "readonly", "override"].map((name): ExpectedCompletionEntryObject => ({
11791179
name,
11801180
kind: "keyword",
11811181
sortText: SortText.GlobalsOrKeywords

tests/baselines/reference/api/tsserverlibrary.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,7 @@ declare namespace ts {
540540
Override = 16384,
541541
HasComputedFlags = 536870912,
542542
AccessibilityModifier = 28,
543-
ParameterPropertyModifier = 92,
543+
ParameterPropertyModifier = 16476,
544544
NonPublicAccessibilityModifier = 24,
545545
TypeScriptModifier = 18654,
546546
ExportDefault = 513,

tests/baselines/reference/api/typescript.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,7 @@ declare namespace ts {
540540
Override = 16384,
541541
HasComputedFlags = 536870912,
542542
AccessibilityModifier = 28,
543-
ParameterPropertyModifier = 92,
543+
ParameterPropertyModifier = 16476,
544544
NonPublicAccessibilityModifier = 24,
545545
TypeScriptModifier = 18654,
546546
ExportDefault = 513,

tests/baselines/reference/override11.errors.txt

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tests/cases/conformance/override/override11.ts(6,18): error TS1090: 'override' modifier cannot appear on a parameter.
1+
tests/cases/conformance/override/override11.ts(6,27): error TS1029: 'public' modifier must precede 'override' modifier.
22

33

44
==== tests/cases/conformance/override/override11.ts (1 errors) ====
@@ -8,8 +8,8 @@ tests/cases/conformance/override/override11.ts(6,18): error TS1090: 'override' m
88

99
class Sub extends Base {
1010
constructor (override public foo: number) {
11-
~~~~~~~~
12-
!!! error TS1090: 'override' modifier cannot appear on a parameter.
11+
~~~~~~
12+
!!! error TS1029: 'public' modifier must precede 'override' modifier.
1313
super();
1414
}
1515
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
tests/cases/conformance/override/overrideParameterProperty.ts(20,24): error TS1029: 'public' modifier must precede 'override' modifier.
2+
tests/cases/conformance/override/overrideParameterProperty.ts(25,5): error TS2369: A parameter property is only allowed in a constructor implementation.
3+
4+
5+
==== tests/cases/conformance/override/overrideParameterProperty.ts (2 errors) ====
6+
class Base {
7+
p1!: string;
8+
}
9+
10+
class C1 extends Base {
11+
constructor(public override p1: "hello") {
12+
super();
13+
this.p1;
14+
}
15+
}
16+
17+
class C2 extends Base {
18+
constructor(override p1: "hello") {
19+
super();
20+
this.p1;
21+
}
22+
}
23+
24+
class C3 extends Base {
25+
constructor(override public p1: "hello") {
26+
~~~~~~
27+
!!! error TS1029: 'public' modifier must precede 'override' modifier.
28+
super();
29+
this.p1;
30+
}
31+
32+
m(override p1: "hello") {}
33+
~~~~~~~~~~~~~~~~~~~~
34+
!!! error TS2369: A parameter property is only allowed in a constructor implementation.
35+
}
36+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
//// [overrideParameterProperty.ts]
2+
class Base {
3+
p1!: string;
4+
}
5+
6+
class C1 extends Base {
7+
constructor(public override p1: "hello") {
8+
super();
9+
this.p1;
10+
}
11+
}
12+
13+
class C2 extends Base {
14+
constructor(override p1: "hello") {
15+
super();
16+
this.p1;
17+
}
18+
}
19+
20+
class C3 extends Base {
21+
constructor(override public p1: "hello") {
22+
super();
23+
this.p1;
24+
}
25+
26+
m(override p1: "hello") {}
27+
}
28+
29+
30+
//// [overrideParameterProperty.js]
31+
var __extends = (this && this.__extends) || (function () {
32+
var extendStatics = function (d, b) {
33+
extendStatics = Object.setPrototypeOf ||
34+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
35+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
36+
return extendStatics(d, b);
37+
};
38+
return function (d, b) {
39+
if (typeof b !== "function" && b !== null)
40+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
41+
extendStatics(d, b);
42+
function __() { this.constructor = d; }
43+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
44+
};
45+
})();
46+
var Base = /** @class */ (function () {
47+
function Base() {
48+
}
49+
return Base;
50+
}());
51+
var C1 = /** @class */ (function (_super) {
52+
__extends(C1, _super);
53+
function C1(p1) {
54+
var _this = _super.call(this) || this;
55+
_this.p1 = p1;
56+
_this.p1;
57+
return _this;
58+
}
59+
return C1;
60+
}(Base));
61+
var C2 = /** @class */ (function (_super) {
62+
__extends(C2, _super);
63+
function C2(p1) {
64+
var _this = _super.call(this) || this;
65+
_this.p1 = p1;
66+
_this.p1;
67+
return _this;
68+
}
69+
return C2;
70+
}(Base));
71+
var C3 = /** @class */ (function (_super) {
72+
__extends(C3, _super);
73+
function C3(p1) {
74+
var _this = _super.call(this) || this;
75+
_this.p1 = p1;
76+
_this.p1;
77+
return _this;
78+
}
79+
C3.prototype.m = function (p1) { };
80+
return C3;
81+
}(Base));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
=== tests/cases/conformance/override/overrideParameterProperty.ts ===
2+
class Base {
3+
>Base : Symbol(Base, Decl(overrideParameterProperty.ts, 0, 0))
4+
5+
p1!: string;
6+
>p1 : Symbol(Base.p1, Decl(overrideParameterProperty.ts, 0, 12))
7+
}
8+
9+
class C1 extends Base {
10+
>C1 : Symbol(C1, Decl(overrideParameterProperty.ts, 2, 1))
11+
>Base : Symbol(Base, Decl(overrideParameterProperty.ts, 0, 0))
12+
13+
constructor(public override p1: "hello") {
14+
>p1 : Symbol(C1.p1, Decl(overrideParameterProperty.ts, 5, 14))
15+
16+
super();
17+
>super : Symbol(Base, Decl(overrideParameterProperty.ts, 0, 0))
18+
19+
this.p1;
20+
>this.p1 : Symbol(C1.p1, Decl(overrideParameterProperty.ts, 5, 14))
21+
>this : Symbol(C1, Decl(overrideParameterProperty.ts, 2, 1))
22+
>p1 : Symbol(C1.p1, Decl(overrideParameterProperty.ts, 5, 14))
23+
}
24+
}
25+
26+
class C2 extends Base {
27+
>C2 : Symbol(C2, Decl(overrideParameterProperty.ts, 9, 1))
28+
>Base : Symbol(Base, Decl(overrideParameterProperty.ts, 0, 0))
29+
30+
constructor(override p1: "hello") {
31+
>p1 : Symbol(C2.p1, Decl(overrideParameterProperty.ts, 12, 14))
32+
33+
super();
34+
>super : Symbol(Base, Decl(overrideParameterProperty.ts, 0, 0))
35+
36+
this.p1;
37+
>this.p1 : Symbol(C2.p1, Decl(overrideParameterProperty.ts, 12, 14))
38+
>this : Symbol(C2, Decl(overrideParameterProperty.ts, 9, 1))
39+
>p1 : Symbol(C2.p1, Decl(overrideParameterProperty.ts, 12, 14))
40+
}
41+
}
42+
43+
class C3 extends Base {
44+
>C3 : Symbol(C3, Decl(overrideParameterProperty.ts, 16, 1))
45+
>Base : Symbol(Base, Decl(overrideParameterProperty.ts, 0, 0))
46+
47+
constructor(override public p1: "hello") {
48+
>p1 : Symbol(C3.p1, Decl(overrideParameterProperty.ts, 19, 14))
49+
50+
super();
51+
>super : Symbol(Base, Decl(overrideParameterProperty.ts, 0, 0))
52+
53+
this.p1;
54+
>this.p1 : Symbol(C3.p1, Decl(overrideParameterProperty.ts, 19, 14))
55+
>this : Symbol(C3, Decl(overrideParameterProperty.ts, 16, 1))
56+
>p1 : Symbol(C3.p1, Decl(overrideParameterProperty.ts, 19, 14))
57+
}
58+
59+
m(override p1: "hello") {}
60+
>m : Symbol(C3.m, Decl(overrideParameterProperty.ts, 22, 3))
61+
>p1 : Symbol(p1, Decl(overrideParameterProperty.ts, 24, 4))
62+
}
63+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
=== tests/cases/conformance/override/overrideParameterProperty.ts ===
2+
class Base {
3+
>Base : Base
4+
5+
p1!: string;
6+
>p1 : string
7+
}
8+
9+
class C1 extends Base {
10+
>C1 : C1
11+
>Base : Base
12+
13+
constructor(public override p1: "hello") {
14+
>p1 : "hello"
15+
16+
super();
17+
>super() : void
18+
>super : typeof Base
19+
20+
this.p1;
21+
>this.p1 : "hello"
22+
>this : this
23+
>p1 : "hello"
24+
}
25+
}
26+
27+
class C2 extends Base {
28+
>C2 : C2
29+
>Base : Base
30+
31+
constructor(override p1: "hello") {
32+
>p1 : "hello"
33+
34+
super();
35+
>super() : void
36+
>super : typeof Base
37+
38+
this.p1;
39+
>this.p1 : "hello"
40+
>this : this
41+
>p1 : "hello"
42+
}
43+
}
44+
45+
class C3 extends Base {
46+
>C3 : C3
47+
>Base : Base
48+
49+
constructor(override public p1: "hello") {
50+
>p1 : "hello"
51+
52+
super();
53+
>super() : void
54+
>super : typeof Base
55+
56+
this.p1;
57+
>this.p1 : "hello"
58+
>this : this
59+
>p1 : "hello"
60+
}
61+
62+
m(override p1: "hello") {}
63+
>m : (p1: "hello") => void
64+
>p1 : "hello"
65+
}
66+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// @noImplicitOverride: true
2+
3+
class Base {
4+
p1!: string;
5+
}
6+
7+
class C1 extends Base {
8+
constructor(public override p1: "hello") {
9+
super();
10+
this.p1;
11+
}
12+
}
13+
14+
class C2 extends Base {
15+
constructor(override p1: "hello") {
16+
super();
17+
this.p1;
18+
}
19+
}
20+
21+
class C3 extends Base {
22+
constructor(override public p1: "hello") {
23+
super();
24+
this.p1;
25+
}
26+
27+
m(override p1: "hello") {}
28+
}

0 commit comments

Comments
 (0)