Javascript Flowtype:动态扩展类

Javascript Flowtype:动态扩展类,javascript,flowtype,Javascript,Flowtype,是否可以为现有类手动定义其他方法 我的具体用例是蓝鸟的promisifyAll(),它: 通过检查对象的属性并为对象及其原型链上的每个函数创建一个异步等效项,来实现整个对象 显然,flow无法自动解决这个问题。所以,我愿意帮助它。问题是怎么做 考虑以下代码 import http from 'http' import { promisifyAll } from 'bluebird' promisifyAll(http) const server = http.createServer(()

是否可以为现有类手动定义其他方法

我的具体用例是蓝鸟的
promisifyAll()
,它:

通过检查对象的属性并为对象及其原型链上的每个函数创建一个异步等效项,来实现整个对象

显然,flow无法自动解决这个问题。所以,我愿意帮助它。问题是怎么做

考虑以下代码

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在此给出以下错误:

property `listenAsync`. Property not found in
Server

如果我使用
listen
,就不会有任何错误。flow足够聪明,可以看出这是模块中定义的真实方法。但是,
listenAsync
是由
promisifyAll
动态添加的,对flow是不可见的

这是不可能的,也不是真正安全的。以下是您可以为您的案例做的一些事情:

首先声明蓝鸟如下:

declare module "bluebird" {
  declare function promisifyAll(arg: any): any
}
然后这样做:

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)
从“http”导入httpNode
从“蓝鸟”导入{promisifyAll}
从“http”导入类型{Server}
输入PromisifiedServer=Server&{
listenAsync(端口号,主机名?:字符串,待办事项?:编号):承诺;
};
类型PromisifiedHttp={
createServer(监听器:函数):PromisifiedServer;
};
const http:PromisifiedHttp=promisifyAll(httpNode)

在这里,我们手动将
http
转换为type
PromisifiedHttp
。尽管我们可以使用类型交集扩展现有类型,但我们仍然必须手动声明所有Promisified类型。

谢谢。这不是完美的,因为它需要更改代码。微小的变化,但仍然存在。这意味着,对于其他动态情况,代码也必须更改。我理解“不会真正安全”的部分,但这并不现实,因为在这两种情况下,编译器都无法从代码中推断数据,并相信我能编写正确的定义。一般来说,不可能在流中表达某些动态模式。您必须将过于动态的部分从流中分离出来,并为类型化的部分提供适当的声明。如果流有一种以“不安全”的方式进行原型扩展之类的操作的机制,那么这将大大减少曲线。例如,如果我使用像should.js或chai这样的库,我应该能够在libs中创建一个接口,用'should'函数扩展对象的原型。如果这不能以类型安全的方式完成,则允许使用者禁用对使用它的代码路径的静态分析,而不是抛出错误。