microsoft / microsoft/TypeScript
Interface with readonly property is assignable to interface with mutable property
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.3k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 132
Description
TypeScript Version: 2.1.4
Code
interface MutableValue<T> {
value: T;
}
interface ImmutableValue<T> {
readonly value: T;
}
let i: ImmutableValue<string> = { value: "hi" };
i.value = "Excellent, I can't change it"; // compile-time error
let m: MutableValue<string> = 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<number> = 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<T> {
getValue(): T;
setValue(v: T): void;
}
interface ImmutableValue<T> {
getValue(): T;
}
declare let i: ImmutableValue<string>;
i.setValue("Excellent, I can't change it"); // compile-time error
let m: MutableValue<string> = 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).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the TypeScript 2.1.4 reproduction in this issue, comparing assignability for readonly properties with the separate getter/setter interfaces. Review the linked discussion about the deliberate current behavior and determine the compatibility or strict-mode implications; done means the requested assignment is rejected without breaking the documented readonly-array behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100