microsoft/TypeScript (original) (raw)
TypeScript Version: 2.1.4
Code
interface MutableValue { value: T; }
interface ImmutableValue { readonly value: T; }
let i: ImmutableValue = { value: "hi" }; i.value = "Excellent, I can't change it"; // compile-time error
let m: MutableValue = i; m.value = "Oh dear, I can change it";
Expected behavior:
The assignment of i
to m
would fail, to stop us accidentally allowing value
to be modified.
Actual behavior:
The assignment is allowed.
The current behaviour was a deliberate choice so this is a breaking change (or strict flag) feature request rather than a bug report!
The Handbook has this snippet:
let a: number[] = [1, 2, 3, 4]; let ro: ReadonlyArray = a; ro[0] = 12; // error! ro.push(5); // error! ro.length = 100; // error! a = ro; // error!
It notes that a = ro
being an error is helpful. But this happens because ReadonlyArray
has no push
method, making it incompatible with Array
.
My example above seems "morally equivalent" to modelling the input/output flow of values with separate methods:
interface MutableValue { getValue(): T; setValue(v: T): void; }
interface ImmutableValue { getValue(): T; }
declare let i: ImmutableValue; i.setValue("Excellent, I can't change it"); // compile-time error
let m: MutableValue = i; m.setValue("Oh dear, I can change it");
And sure enough, this stops the assignment of i
to m
.
Would be great if mutable and readonly properties had the same relationship as if they were modelled by separate get/set methods (which of course they might actually be, via property getter/setters).