Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flowtype: dynamically extending classes

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

like image 749
JimiDini Avatar asked Feb 02 '16 15:02

JimiDini


1 Answers

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.

like image 106
vkurchatkin Avatar answered Sep 20 '22 20:09

vkurchatkin