What are the differences between readonly vs get in TypeScript properties?
It makes a difference to the generated JavaScript: The getter will be an accessor property (e.g., function), the readonly
property will be a data property. This:
class Example {
get foo(): string {
return "foo";
}
readonly bar: string = "bar";
}
converts to this if you target ES2015+:
"use strict";
class Example {
constructor() {
this.bar = "bar";
}
get foo() {
return "foo";
}
}
Live on the playground
or to this if you target ES5+:
"use strict";
var Example = /** @class */ (function () {
function Example() {
this.bar = "bar";
}
Object.defineProperty(Example.prototype, "foo", {
get: function () {
return "foo";
},
enumerable: true,
configurable: true
});
return Example;
}());
Live on the playground
Notice that although TypeScript considers bar
read-only, nothing enforces that at runtime. foo
, on the other hand, is read-only even at runtime. (Although if you really wanted to, you could use Object.defineProperty
to defeat it by reconfiguring the property.)
A getter is evaluated again on every property access, and creates a new value. This is an important functional difference, as that behaviour is usually not what you want:
class Example {
get foo(): object {
return {};
}
readonly bar: object = {};
}
const example: Example = new Example;
console.log(example.foo === example.foo); // false
console.log(example.bar === example.bar); // true
For the implementation details, see @T.J.Crowder's excellent answer which I won't repeat here.