Recently, there has been an update in TypeScript that triggers a compilation error when attempting to override a property in the base class with a getter/setter pair. This issue arises from property access augmentation:
class BaseClass {
prop : string = 'base_class'
}
class SubClass extends BaseClass {
_prop : string = 'sub_class'
/*
ERROR: 'prop' is defined as a property in class 'BaseClass', but is overridden here in 'SubClass' as an accessor.
*/
get prop () : string {
return this._prop
}
set prop (value : string) {
this._prop = value
}
}
// try running this snippet with `useDefineForClassFields : true` and `useDefineForClassFields : false`
console.log((new SubClass).prop)
This error stems from the fact that class fields in modern JavaScript now have [[DEFINE]] semantic. As a result, the example above may not behave as expected if the compiler option useDefineForClassFields
is set to true
. More information can be found here.
The Evolution of Property Access Augmentation
It is worth noting that historically, the DEFINE semantic for class properties was not widely used. Most JavaScript and TypeScript code currently operates under the assumption of SET semantic for class fields.
The property access augmentation pattern, which involves overriding properties in a base class using getter/setter accessors, is considered valid under the SET semantic. This pattern, often seen in JavaScript code, allows for triggering custom actions on property read/write operations.
Previously, TypeScript and JavaScript primarily relied on SET semantic for class fields. The introduction of the DEFINE semantic led to the new compiler configuration useDefineForClassFields
, which governs the behavior of class fields and is disabled by default due to its potential impact on existing codebases.
Pondering Points:
- Do you believe that the property access augmentation pattern should remain supported by TypeScript under SET semantic (
useDefineForClassFields=false
, the default setting)? - Have you implemented this pattern in your JavaScript/TypeScript projects? If so, kindly share examples of its usage.
Further reading: Proposal suggesting restriction of the compilation error to DEFINE semantic only