Description
π Search Terms
readonly double twice initializer
π Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about initializers?
β― Playground Link
π» Code
class Foo {
readonly bar: string = 'initializer 1';
constructor() {
this.bar = 'initializer 2';
}
}
console.log(new Foo().bar);
π Actual behavior
This compiles successfully despite overwriting a readonly
field. This breaks expectations around readonly
. If Foo
happens to be a very large class and I only look at readonly bar: string = 'initializer 1';
in isolation, I would expect any other line which reads bar
to see initializer 1
. However this is not a safe assumption because I need to check in the constructor to ensure it doesn't overwrite my readonly
field.
π Expected behavior
I expected a compiler error. TS should only allow initializing readonly
fields in a constructor, not overwriting a field which has already been initialized.
Additional information about the issue
I get that we need readonly
fields to be assignable in the constructor, but it feels like a bug to me that this is allowed when the field has already been initialized prior to the constructor. readonly
should require a field initializer xor a constructor initializer. Having both is invalid IMHO.
You can make the same argument that double initializing in the constructor should be invalid too:
class Foo {
readonly bar: string;
constructor() {
this.bar = 'initializer 1';
this.bar = 'initializer 2'; // Should maybe error? Doesn't today.
}
}
But I understand that control flow analysis gets a lot more complicated in the constructor WRT readonly
and might be considered a different feature with different priority.