2

我有一個TypeScript接口,它具有一個名爲「send」的函數,該函數被兩個允許的簽名重載。創建實現具有重載函數的接口的匿名對象

export interface ConnectionContext { 
    send(data: ConnectionData): void; 
    send(data: ConnectionData, timeout: number): Promise<ConnectionData>; 
} 

我試圖創建一個實現此接口的匿名對象:

const context: ConnectionContext = { 
    send: (data: ConnectionData, timeout?: number): void | Promise<ConnectionData> => { 
     // 
    } 
}; 

然而,打字稿2.4.1是生產以下錯誤:

Error:(58, 15) TS2322:Type '{ send: (data: ConnectionData, timeout?: number | undefined) => void | Promise<ConnectionData>; }' is not assignable to type 'ConnectionContext'.

Types of property 'send' are incompatible.

Type '(data: ConnectionData, timeout?: number | undefined) => void | Promise<ConnectionData>' is not assignable to type '{ (data: ConnectionData): void; (data: ConnectionData, timeout: number): Promise<ConnectionData>; }'.

Type 'void | Promise<ConnectionData>' is not assignable to type 'Promise<ConnectionData>'.

Type 'void' is not assignable to type 'Promise<ConnectionData>'.

我知道我可以用一個類做到這一點,但如果有一些方法來做到這一點沒有一個我寧可不創建一個完整的類。

+0

我一直有一個類似的問題,也對此一般性答案感到好奇。 – bcherny

回答

1

想通了 - 如果函數有重載簽名,請輸入基函數any。這是違反直覺的,但是TypeScript目前是如何工作的。

固定碼:

export interface ConnectionContext { 
    send(data: ConnectionData): void; 
    send(data: ConnectionData, timeout: number): Promise<ConnectionData>; 
} 

const context: ConnectionContext = { 
    send: (data: ConnectionData, timeout?: number): any => {} 
}; 

let a = context.send(1)  // void 
let b = context.send(1, 2) // Promise<ConnectionData> 

TypeScript playground link

請參閱從TypeScript Handbook's functions section的最後一段:

注意,function pickCard(x): any件無過載列表的一部分,所以只有兩個重載:一個接受一個對象,一個接受一個數字。使用任何其他參數類型調用pickCard會導致錯誤。