Consider the following class:
export class Foo {
id: string;
static readonly questionKeyPrefix: string;
constructor(id: string, _key: string) {
this.id = id;
if (!Foo.questionKeyPrefix) {
// Error: Cannot assign to 'questionKeyPrefix' because it is a read-only property
Foo.questionKeyPrefix = _key;
}
}
}
When I try to set questionKeyPrefix
which is a static readonly property, it complians. I also add the considition to make sure it is set only once!
If I remove the static everything will be fine!
Any idea how to fix this issue?
2
Answers
In TS you can use static blocks to initalize static members.
Unfortunately you Cannot assign readonly statics in static blocks #56584
The way your code is designed at the moment, it can’t work, because you have a static property whose value can change every time the constructor is invoked. Such a property cannot be
readonly
because its value can be observed to change after initialisation.However, from the comments it seems this doesn’t really model what you’re trying to achieve, because you want this property to have a different value per subclass, just not a different value per instance.
The simplest solution is to make it an instance property regardless, and just give that instance property the appropriate value based on its subclass. An instance property doesn’t need to be a constructor parameter for every subclass; you can pass it from the subclass’s constructor:
Playground Link
An alternative, if you are concerned about this being a property (e.g. because it shows up when you serialize the object), is to make this a "virtual" property with
get
:Playground Link
Since the getter is declared per subclass, the value is per subclass rather than per instance.
Generally speaking, "static per subclass" is not a very useful thing to do, because static properties are not normally accessed polymorphically. This would only make sense if the classes themselves were to be passed around as values, e.g.
Playground Link
Assuming you aren’t doing this, then there is no value in making something "static per class", because you can’t access it polymorphically from an instance context.
this.key
won’t work, andBase.key
isn’t polymorphic; you would just get the value of the base class’s static property, regardless of what subclassthis
belongs to.