I have a Javascript file that looks like this:
// @flow
/**
* My database module.
*
* Interact with the database.
*/
'use strict';
module.exports = {
/** Mockable wrapper around mongoose. */
mongoose: function() /*:: : Object */ {
// $FlowExpectedError
return require('mongoose');
},
/** Mockable wrapper around env. */
env: function() /*:: : Object */ {
// $FlowExpectedError
return require('./env.js');
},
/** Initialize the connection to Mongoose. */
init: function(
callbackOK /*:: : () => number */,
callbackInitError /*:: : (x: string) => null */,
callbackError /*:: : (x: string) => null */) {
try {
// See https://mongoosejs.com/docs/connections.html.
this.mongoose().connect(this.uri(), {}).then(
() => callbackOK(),
err => callbackInitError(err),
);
this.mongoose().connection.on('error',
err => callbackError(err),
);
}
catch (err) {
callbackInitError(err);
}
},
/** Get the connection URI for the Mongoose database. */
uri: function() /*:: : string */ {
const user = String(this.env().required('MONGO_USER'));
const pass = String(this.env().required('MONGO_PASS'));
const host = String(this.env().required('MONGO_HOST'));
const port = String(this.env().required('MONGO_PORT'));
const db = String(this.env().required('MONGO_DB'));
return 'mongodb://' + user + ':' + pass + '@' + host + ':' + port + '/' + db + '?authSource=admin';
},
};
When I check it with Flow, it gives me this error:
Missing an annotation on implicit `this` parameter of function. [missing-this-annot]
v
24| init: function(
25| callbackOK /*:: : () => number */,
26| callbackInitError /*:: : (x: string) => null */,
27| callbackError /*:: : (x: string) => null */) {
-------------------------------------------^
How would I modify this code to fix this error?
Reason
According to https://medium.com/flow-type/sound-typing-for-this-in-flow-d62db2af969e, you have to explicitly type the
Thisparameter.Let's just say that Flow was not producing any error here. Then Flow could not prevent you to do this:
But this will throw at runtime as global
thisdoesn't have anenvfunction.Solution 1
You could define a type for your module:
Then in the functions where you call
this, you would have to add a specialthisannotation:This shouldn't change the function signature as long as you have have a recent version of Babel (at least 7.13.0 according to the article above).
Flow try link
Solution 2
You might not like defining the types into two different places. Then why not get rid of
thisaltogether?Declare each function at the top level, e.g.
And then export them:
Flow try link