Assuming a library with a function like:
class Stuff {
total () {
return 4; // might be some calculation
}
}
But you want to update it to use a getter, like:
class Stuff {
get total () {
return 4;
}
}
Is there a way to make a change like this in a backwards compatible way? So code that uses the library assuming a function doesn't break?
stuff.total // should work with new version
stuff.total() // hopefully this still works
Edit: This question is more about library evolution (more general). The other one is about a particular solution and from a call-site perspective.
You should not do this. stuff.total
should either be a number or a function, but not both. That will make for very confusing and difficult to maintain code in the future.
That said, you can do something along the lines of what you want:
class Stuff {
get total () {
const callable = function ( ) {
return 4;
};
callable[Symbol.toPrimitive] = callable;
return callable;
}
}
const stuff = new Stuff;
console.log( stuff.total );
console.log( stuff.total( ) );
console.log( 1 + stuff.total );
console.log( 1 + stuff.total( ) );
// stuff.total is a function, not a number!
console.log( typeof stuff.total );
console.log( stuff.total.toString( ) );
// But if it's implicitly coerced to a string, it's toString is not called:
console.log( '' + stuff.total);
console.log( `${stuff.total}` );
There are some caveats though. stuff.total
is a getter here that is returning a function, not a number. Using that function anywhere a primitive is expected results in the function being called and it's return value being used instead, but it is still really a function. That is evident when you log stuff.total.toString( )
or typeof stuff.total
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With