-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Fix #7590: Allow 'readonly' to be used in constructor parameters #8555
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
ad2634e
a9742c5
02f2ed7
40afe4a
ce59673
22ee90a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -407,8 +407,10 @@ namespace ts { | |
HasAggregatedChildData = 1 << 29, // If we've computed data from children and cached it in this node | ||
HasJsxSpreadAttribute = 1 << 30, | ||
|
||
Modifier = Export | Ambient | Public | Private | Protected | Static | Abstract | Default | Async, | ||
Modifier = Export | Ambient | Public | Private | Protected | Static | Abstract | Default | Async | Readonly, | ||
AccessibilityModifier = Public | Private | Protected, | ||
// Accessibility modifiers and 'readonly' can be attached to a parameter in a constructor to make it a property. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The term for this is a "parameter property", so maybe a better name for the flag would be |
||
ParameterPropertyModifier = AccessibilityModifier | Readonly, | ||
BlockScoped = Let | Const, | ||
|
||
ReachabilityCheckFlags = HasImplicitReturn | HasExplicitReturn, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,14 @@ | ||
tests/cases/compiler/accessorParameterAccessibilityModifier.ts(3,9): error TS2369: A parameter property is only allowed in a constructor implementation. | ||
tests/cases/compiler/accessorParameterAccessibilityModifier.ts(3,11): error TS2369: A parameter property is only allowed in a constructor implementation. | ||
tests/cases/compiler/accessorParameterAccessibilityModifier.ts(4,16): error TS2369: A parameter property is only allowed in a constructor implementation. | ||
tests/cases/compiler/accessorParameterAccessibilityModifier.ts(4,18): error TS2369: A parameter property is only allowed in a constructor implementation. | ||
|
||
|
||
==== tests/cases/compiler/accessorParameterAccessibilityModifier.ts (4 errors) ==== | ||
==== tests/cases/compiler/accessorParameterAccessibilityModifier.ts (2 errors) ==== | ||
|
||
class C { | ||
set X(public v) { } | ||
~ | ||
!!! error TS2369: A parameter property is only allowed in a constructor implementation. | ||
~~~~~~~~ | ||
!!! error TS2369: A parameter property is only allowed in a constructor implementation. | ||
static set X(public v2) { } | ||
~ | ||
!!! error TS2369: A parameter property is only allowed in a constructor implementation. | ||
~~~~~~~~~ | ||
!!! error TS2369: A parameter property is only allowed in a constructor implementation. | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
//// [declarationEmit_readonly.ts] | ||
|
||
class C { | ||
constructor(readonly x: number) {} | ||
} | ||
|
||
//// [declarationEmit_readonly.js] | ||
var C = (function () { | ||
function C(x) { | ||
this.x = x; | ||
} | ||
return C; | ||
}()); | ||
|
||
|
||
//// [declarationEmit_readonly.d.ts] | ||
declare class C { | ||
readonly x: number; | ||
constructor(x: number); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
=== tests/cases/conformance/classes/constructorDeclarations/constructorParameters/declarationEmit_readonly.ts === | ||
|
||
class C { | ||
>C : Symbol(C, Decl(declarationEmit_readonly.ts, 0, 0)) | ||
|
||
constructor(readonly x: number) {} | ||
>x : Symbol(C.x, Decl(declarationEmit_readonly.ts, 2, 16)) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
=== tests/cases/conformance/classes/constructorDeclarations/constructorParameters/declarationEmit_readonly.ts === | ||
|
||
class C { | ||
>C : C | ||
|
||
constructor(readonly x: number) {} | ||
>x : number | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,9 @@ | ||
tests/cases/conformance/parser/ecmascript5/MemberAccessorDeclarations/parserMemberAccessorDeclaration15.ts(2,8): error TS2369: A parameter property is only allowed in a constructor implementation. | ||
tests/cases/conformance/parser/ecmascript5/MemberAccessorDeclarations/parserMemberAccessorDeclaration15.ts(2,12): error TS2369: A parameter property is only allowed in a constructor implementation. | ||
|
||
|
||
==== tests/cases/conformance/parser/ecmascript5/MemberAccessorDeclarations/parserMemberAccessorDeclaration15.ts (2 errors) ==== | ||
==== tests/cases/conformance/parser/ecmascript5/MemberAccessorDeclarations/parserMemberAccessorDeclaration15.ts (1 errors) ==== | ||
class C { | ||
set Foo(public a: number) { } | ||
~~~ | ||
!!! error TS2369: A parameter property is only allowed in a constructor implementation. | ||
~~~~~~~~~~~~~~~~ | ||
!!! error TS2369: A parameter property is only allowed in a constructor implementation. | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
tests/cases/conformance/classes/constructorDeclarations/constructorParameters/readonlyInAmbientClass.ts(2,14): error TS2369: A parameter property is only allowed in a constructor implementation. | ||
tests/cases/conformance/classes/constructorDeclarations/constructorParameters/readonlyInAmbientClass.ts(3,9): error TS2369: A parameter property is only allowed in a constructor implementation. | ||
|
||
|
||
==== tests/cases/conformance/classes/constructorDeclarations/constructorParameters/readonlyInAmbientClass.ts (2 errors) ==== | ||
declare class C{ | ||
constructor(readonly x: number); | ||
~~~~~~~~~~~~~~~~~~ | ||
!!! error TS2369: A parameter property is only allowed in a constructor implementation. | ||
method(readonly x: number); | ||
~~~~~~~~~~~~~~~~~~ | ||
!!! error TS2369: A parameter property is only allowed in a constructor implementation. | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
//// [readonlyInAmbientClass.ts] | ||
declare class C{ | ||
constructor(readonly x: number); | ||
method(readonly x: number); | ||
} | ||
|
||
//// [readonlyInAmbientClass.js] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
tests/cases/conformance/classes/constructorDeclarations/constructorParameters/readonlyInConstructorParameters.ts(4,1): error TS2450: Left-hand side of assignment expression cannot be a constant or a read-only property. | ||
tests/cases/conformance/classes/constructorDeclarations/constructorParameters/readonlyInConstructorParameters.ts(7,26): error TS1029: 'public' modifier must precede 'readonly' modifier. | ||
tests/cases/conformance/classes/constructorDeclarations/constructorParameters/readonlyInConstructorParameters.ts(13,10): error TS2341: Property 'x' is private and only accessible within class 'F'. | ||
|
||
|
||
==== tests/cases/conformance/classes/constructorDeclarations/constructorParameters/readonlyInConstructorParameters.ts (3 errors) ==== | ||
class C { | ||
constructor(readonly x: number) {} | ||
} | ||
new C(1).x = 2; | ||
~~~~~~~~~~ | ||
!!! error TS2450: Left-hand side of assignment expression cannot be a constant or a read-only property. | ||
|
||
class E { | ||
constructor(readonly public x: number) {} | ||
~~~~~~ | ||
!!! error TS1029: 'public' modifier must precede 'readonly' modifier. | ||
} | ||
|
||
class F { | ||
constructor(private readonly x: number) {} | ||
} | ||
new F(1).x; | ||
~ | ||
!!! error TS2341: Property 'x' is private and only accessible within class 'F'. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
//// [readonlyInConstructorParameters.ts] | ||
class C { | ||
constructor(readonly x: number) {} | ||
} | ||
new C(1).x = 2; | ||
|
||
class E { | ||
constructor(readonly public x: number) {} | ||
} | ||
|
||
class F { | ||
constructor(private readonly x: number) {} | ||
} | ||
new F(1).x; | ||
|
||
//// [readonlyInConstructorParameters.js] | ||
var C = (function () { | ||
function C(x) { | ||
this.x = x; | ||
} | ||
return C; | ||
}()); | ||
new C(1).x = 2; | ||
var E = (function () { | ||
function E(x) { | ||
this.x = x; | ||
} | ||
return E; | ||
}()); | ||
var F = (function () { | ||
function F(x) { | ||
this.x = x; | ||
} | ||
return F; | ||
}()); | ||
new F(1).x; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
tests/cases/compiler/readonlyInNonPropertyParameters.ts(4,9): error TS2369: A parameter property is only allowed in a constructor implementation. | ||
tests/cases/compiler/readonlyInNonPropertyParameters.ts(5,8): error TS2369: A parameter property is only allowed in a constructor implementation. | ||
tests/cases/compiler/readonlyInNonPropertyParameters.ts(7,2): error TS2369: A parameter property is only allowed in a constructor implementation. | ||
|
||
|
||
==== tests/cases/compiler/readonlyInNonPropertyParameters.ts (3 errors) ==== | ||
|
||
// `readonly` won't work outside of property parameters | ||
class X { | ||
method(readonly x: number) {} | ||
~~~~~~~~~~~~~~~~~~ | ||
!!! error TS2369: A parameter property is only allowed in a constructor implementation. | ||
set x(readonly value: number) {} | ||
~~~~~~~~~~~~~~~~~~~~~~ | ||
!!! error TS2369: A parameter property is only allowed in a constructor implementation. | ||
} | ||
(readonly x) => 0; | ||
~~~~~~~~~~ | ||
!!! error TS2369: A parameter property is only allowed in a constructor implementation. | ||
// OK to use `readonly` as a name | ||
(readonly) => 0; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
//// [readonlyInNonPropertyParameters.ts] | ||
|
||
// `readonly` won't work outside of property parameters | ||
class X { | ||
method(readonly x: number) {} | ||
set x(readonly value: number) {} | ||
} | ||
(readonly x) => 0; | ||
// OK to use `readonly` as a name | ||
(readonly) => 0; | ||
|
||
//// [readonlyInNonPropertyParameters.js] | ||
// `readonly` won't work outside of property parameters | ||
var X = (function () { | ||
function X() { | ||
} | ||
X.prototype.method = function (x) { }; | ||
Object.defineProperty(X.prototype, "x", { | ||
set: function (value) { }, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
return X; | ||
}()); | ||
(function (x) { return 0; }); | ||
// OK to use `readonly` as a name | ||
(function (readonly) { return 0; }); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
tests/cases/conformance/classes/constructorDeclarations/constructorParameters/readonlyReadonly.ts(2,14): error TS1030: 'readonly' modifier already seen. | ||
tests/cases/conformance/classes/constructorDeclarations/constructorParameters/readonlyReadonly.ts(3,26): error TS1030: 'readonly' modifier already seen. | ||
|
||
|
||
==== tests/cases/conformance/classes/constructorDeclarations/constructorParameters/readonlyReadonly.ts (2 errors) ==== | ||
class C { | ||
readonly readonly x: number; | ||
~~~~~~~~ | ||
!!! error TS1030: 'readonly' modifier already seen. | ||
constructor(readonly readonly y: number) {} | ||
~~~~~~~~ | ||
!!! error TS1030: 'readonly' modifier already seen. | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
//// [readonlyReadonly.ts] | ||
class C { | ||
readonly readonly x: number; | ||
constructor(readonly readonly y: number) {} | ||
} | ||
|
||
//// [readonlyReadonly.js] | ||
var C = (function () { | ||
function C(y) { | ||
this.y = y; | ||
} | ||
return C; | ||
}()); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
//@target: ES5 | ||
|
||
// `readonly` won't work outside of property parameters | ||
class X { | ||
method(readonly x: number) {} | ||
set x(readonly value: number) {} | ||
} | ||
(readonly x) => 0; | ||
// OK to use `readonly` as a name | ||
(readonly) => 0; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
// @declaration: true | ||
|
||
class C { | ||
constructor(readonly x: number) {} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
declare class C{ | ||
constructor(readonly x: number); | ||
method(readonly x: number); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
class C { | ||
constructor(readonly x: number) {} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also to clarify if it is just There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep. This is the same as for properties. ( |
||
} | ||
new C(1).x = 2; | ||
|
||
class E { | ||
constructor(readonly public x: number) {} | ||
} | ||
|
||
class F { | ||
constructor(private readonly x: number) {} | ||
} | ||
new F(1).x; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
class C { | ||
readonly readonly x: number; | ||
constructor(readonly readonly y: number) {} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you still want to keep
Readonly
in ? since you have made a new flagParameterPropertyModifier
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is a modifier..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
got cha, I got confused why it is here caz i thought it is not direct related with the bug.