Javascript 声明“a”的类型;“承诺人”;在typescript或flow中的函数

Javascript 声明“a”的类型;“承诺人”;在typescript或flow中的函数,javascript,typescript,flowtype,Javascript,Typescript,Flowtype,我得到了这个函数,它基本上将(nodejs)回调风格的函数转换为承诺风格的函数 export const promisify : PromisifyT = ( fn, ...args ) => { return new Promise( (resolve, reject) => { fn( ...args , (err, ...result) => { if (err) return r

我得到了这个函数,它基本上将(nodejs)回调风格的函数转换为承诺风格的函数

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);
const resolveWith=(解析,拒绝)=>(错误,数据)=>
犯错误拒绝(err):解析(数据);
类型解析器=(err:any,data:any)=>void;
类型Nodelike1=(x:A,解析器:解析器)=>void;
类型Nodelike2=(x:A,y:B,解析器:解析器)=>void;
类型Nodelike3=(x:A,y:B,z:C,解析器:解析器)=>void;
功能承诺(fn:Nodelike1,x:A):承诺;
功能承诺(fn:Nodelike2,x:A,y:B):承诺;
功能承诺(fn:Nodelike3,x:A,y:B,z:C):承诺;
功能预测(fn,x,y?,z?){
如果(z!=null){
返回新承诺((解决、拒绝)=>
fn(x,y,z,resolveWith(resolve,reject));
}如果(y!=null),则为else{
返回新承诺((解决、拒绝)=>
fn(x,y,resolveWith(resolve,reject));
}否则{
返回新承诺((解决、拒绝)=>
fn(x,resolveWith(resolve,reject));
}
}
const readFile=promisify((url:string,cb)=>cb(null,“Bob”),url);
如果传入的
url
中有一个字符串,它将顺利工作。如果您传入一个数字,TypeScript将询问您是否指其他内容,因为从传递的函数的签名来看,它需要一个字符串

如您所见,您可以将其扩展到日落,并将其变成一个300行长的快乐包,其中充满了泛型的乐趣,并回顾了参数列表。 作为一个喜欢函数式编程的人,当我实现一个compose或curry时,你无法想象这会让我感觉多么肮脏。。。他们是可怕的。。。在这种情况下,只有当我的代码最初是这样编写的,而不是满足编译器的要求时,类型才会使我的代码更安全

理想情况下,我会更进一步,让
promisify
返回一个函数,该函数期望参数xy和z与传入的函数分开,这样在系统中只会出现一次这样的尴尬


但这是另一天的痛苦。

当我写我的答案时,你可能是指结尾的承诺。。。。理想情况下,你甚至不需要它。我实际上不想担心函数实现中推断的类型,但我实际上不需要那个类型转换…对。你明确地向任何人施压。类型为
Promise
(或
Promise
)。但TypeScript可以在没有帮助的情况下愉快地推断出这一点。这是一个“您编写类型是为了编译器的利益,还是为了您的利益”(因为编译器可能不需要大部分类型)。只有当您试图让它推断承诺中包含的返回类型时,它才需要帮助。