2017-04-24 108 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分別從功能上被傳遞的功能,使其不僅看起來這種尷尬的一次是在系統中。

但這是另一天的痛苦。