Is there a way to fail the compilation of the code like in the example below:
interface Ro {
readonly x: string;
}
const modify = (rw: {x: string;}) => rw.x = 'bye';
const use = (v: Ro) => {
console.log(v.x);
//v.x = 'bye'; Compiler error: "Cannot assign to 'x' because it is a read-only property."
modify(v);// No errors, not even warnings.
}
const ro: Ro = {x: "hi"}
use(ro);
console.log(ro.x);// readonly field has been changed!
CodePudding user response:
There is not a way to fail the compilation currently. There are a few things you can do alternatively:
- Use a lint rule
- Use the technique suggested here which is pretty awkward: Disable allowing assigning Readonly types to non-readonly types
- Be satisfied with a run-time error using
Object.freeze
CodePudding user response:
Here:
const modify = (rw: {x: string;}) => rw.x = 'bye';
you're telling TypeScript to be more lenient than it should be. If you typed the argument correctly const modify = (rw: Ro) => //...
, it would correctly disallow modification.
If we want, we can pretty much always bypass TypeScript safeguards and type checks, by writing things like like myVariable as unknown as any
, or Object.defineProperty
etc. It's not bulletproof.
CodePudding user response:
Probably the only way to achieve this is to use Object.freeze
on the entire object.
Note: this will only apply at run time, the compilation will succeed