modernator modernator - 28 days ago 11
Javascript Question

Add method dynamically/Selective override prototype method in Flow

I have a constructor like this:

function IDBCrud(table: string): void {
...
}

IDBCrud.prototype.get = function(...) { ... }
IDBCrud.prototype.post = function(...) { ... }


And it using like this:

const accounts = new IDBCrud('Accounts');
accounts.get( ... );
accounts.create( ... );


But sometimes, I want to define method to object directly with same name as in property, so that invokes instead of prototype's method.

// Override get method for some reason
accounts.get = function( ... ) {
// Do some stuffs...
...

// Now call prototype get
return this.__proto__.get.apply(this, arguments);
}


But when I ran flow, it fails with this:

16: accounts.get = function(match, options) {
^^^ property `get`. Property not found in
16: accounts.get = function(match, options) {
^^^^^^^^^^^^ new object


Because IDBCrud doesn't have "get" property(or method). But if I just write them with empty value like this:

function IDBCrud(...): ... {
this.get = function() {};
this.create = function() {};
...
}


If should be work in that case, but if do that, I have to redefine every "get" method to invoke prototype's get method.

const accounts = new IDBCrud('accounts');
accounts.get = function() { ... }; // Override
accounts.get(); // works

const users = new IDBCrud('users');
users.get(); // Invokes users.get and it's empty function, instead of prototype.get


I don't wanna do that everytime I made IDBCrud instance, I just want to override it only it needed.

Without flow, it's not a problem, but with it, it fails.

So how do I achieve this with flow? Any advice will very appreciate it.

Answer Source

Flow was intentionally built for supporting es6 class, and it blocks me to add method in runtime for safety reasons.

Solution was simple, convert constructor to class and make new class that extends IDBCrud and override method and it's working now.