javascript - 在 typescript 或流程中声明 "promisifier"函数的类型

标签 javascript typescript flowtype

我有这个函数,它基本上将 (nodejs)callback 风格的函数转换为 Promise 风格的函数。

export const promisify 
    : PromisifyT 
    = ( fn, ...args ) => {
        return new Promise( (resolve, reject) => {
            fn( ...args , (err, ...result) => {
                if (err) return reject(err)
                resolve(result)
            })
        }) as any
    }

我如何声明 PromisifyT 以便 fn 的输入类型正确映射到生成的函数中? (由于仍然不支持可变参数类型参数,我们可以将自己限制为最多 2 或 3 个参数)。这可能吗?

PS:我已经尝试过,但在遇到诸如重载候选匹配错误之类的问题时暂停了一点。

最佳答案

有可能,只是完全不好玩。

我指的是这种完全不有趣的类型:

const resolveWith = (resolve, reject) => (err, data) =>
    err ? reject(err) : resolve(data);

type Resolver = (err:any, data:any) => void;

type Nodelike1<A> = (x:A, resolver:Resolver)=>void;
type Nodelike2<A,B> = (x:A, y:B, resolver:Resolver)=>void;
type Nodelike3<A,B,C> = (x:A, y:B, z:C, resolver:Resolver)=>void;

function promisify <A>(fn:Nodelike1<A>, x:A):Promise<any>;
function promisify <A, B>(fn:Nodelike2<A,B>, x: A, y:B):Promise<any>;
function promisify <A, B, C>(fn:Nodelike3<A,B,C>, x:A, y:B, z:C):Promise<any>;
function promisify (fn, x, y?, z?) {
  if (z != null) {
    return new Promise((resolve, reject) =>
      fn(x, y, z, resolveWith(resolve, reject)));
  } else if (y != null) {
    return new Promise((resolve, reject) =>
      fn(x, y, resolveWith(resolve, reject)));
  } else {
    return new Promise((resolve, reject) =>
      fn(x, resolveWith(resolve, reject)));
  }
}

const readFile = promisify((url:string, cb) => cb(null, "Bob"), url);

如果传入的url是一个字符串,它将顺利工作。如果您传递一个数字,TypeScript 会询问您是否有其他意思,因为从传递的函数签名来看,它需要一个字符串。

正如您所看到的,您可以将其扩展到日落,并将其变成一个快乐的 300 行长包,其中充满了泛型的乐趣,并向后浏览参数列表。 作为一个喜欢函数式编程的人,你无法想象当我实现 compose 或 curry 时,这让我感觉多么肮脏……它们太可怕了……在这种情况下,类型使我的代码更安全的想法是只有当我的代码一开始就是这样编写的,而不是安抚编译器时,才是正确的。

理想情况下,我会更进一步,让 promisify 返回一个函数,该函数期望参数 x y 和 z 与传入的函数分开,这样它只会在系统。

但这又是痛苦的一天。

关于javascript - 在 typescript 或流程中声明 "promisifier"函数的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43596390/

相关文章:

Javascript 获取图像大小 onload

javascript - 使用 Rails 连接 Raphael

javascript - Return/Enter 时取消选择输入框

javascript - typescript :有条件地将对象属性标记为可选?

javascript - 流类型对象中的动态属性名称

css - 样式表.create "not covered by flow"

javascript - 如何修复我的 ReferenceError

javascript - 如何向对象添加键值对?

typescript - 如何解决 PouchDB 的错误(?)TypeScript/DefinitelyTyped 类型?

javascript - 为什么flow在使用instanceof时会给出uncovered code warning?