2017-04-24 74 views
1

我有这个函数,它基本上将(nodejs)回调式函数转换为承诺式函数。在打字稿或流程中声明“promisifier”函数的类型

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:我已经给它一个尝试,但遇到像过载错误候选匹配等问题时暂停了一下。

+0

虽然我写我的答案,你可能确实意味着'作为承诺'在尾端。 ......理想情况下,你甚至不需要这个。 – Norguard

+0

我其实不想担心在函数实现中推断的类型,但我实际上并不需要这种类型的转换... –

+0

没错。你明确地向任何人投射。该类型是'Promise '(或'Promise <{}>')。但是,TypeScript可以愉快地推断没有帮助。这是一个问题,“你是为编译器的好处编写类型还是你的编写类型”(因为编译器可能不需要其中的大部分)。如果您试图推断Promise中包含的返回类型,它只需要帮助。 – Norguard

回答

2

这是可能的,它只是完全没有乐趣。

这完全是不好玩的类型,我是指:

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线长包,充满了仿制药的乐趣,并且通过参数列表向后走。 作为一个喜欢函数式编程的人,你无法想象当我实现一个写作或咖喱时,这让我感觉有多脏......他们很可怕......在这种情况下,这些类型让我的代码更安全只有当我的代码是这样写在第一位,而不是安抚编译器时才是如此。

理想情况下,我会进一步采取这一步骤并进行promisify回报预期的参数x和y和z分别从功能上被传递的功能,使其不仅看起来这种尴尬的一次是在系统中。

但这是另一天的痛苦。