Reputation: 2069
Is it possible to manually define additional methods for an existing class?
My specific usecase is bluebird's promisifyAll()
which:
Promisifies the entire object by going through the object's properties and creating an async equivalent of each function on the object and its prototype chain… http://bluebirdjs.com/docs/api/promise.promisifyall.html
Obviously, flow wouldn't be able to figure this out automatically. So, I'm willing to help it. The question is HOW?
Consider the following code
import http from 'http'
import { promisifyAll } from 'bluebird'
promisifyAll(http)
const server = http.createServer(() => { console.log('request is in'); })
server.listenAsync(8080).then(() => {
console.log('Server is ready to handle connections')
})
Flow gives the following error here:
property `listenAsync`. Property not found in
Server
There wouldn't be any error if I used listen
. flow's smart enough to see that this is a real method defined in a module. But listenAsync
is a dynamic addition by promisifyAll
and is invisible to flow
Upvotes: 6
Views: 1970
Reputation: 13570
That's not possible and that would not be really safe to do. Here is something you can do for your case:
first declare bluebird
as following:
declare module "bluebird" {
declare function promisifyAll(arg: any): any
}
Then do this:
import httpNode from 'http'
import { promisifyAll } from 'bluebird'
import type { Server } from 'http'
type PromisifiedServer = Server & {
listenAsync(port: number, hostname?: string, backlog?: number): Promise<PromisifiedServer>;
};
type PromisifiedHttp = {
createServer(listener: Function): PromisifiedServer;
};
const http: PromisifiedHttp = promisifyAll(httpNode)
Here we manually cast http
to type PromisifiedHttp
. We still have to declare all promisifed types manually, although we can use type intersection to extends existing types.
Upvotes: 7