2017-01-16 58 views
0

我想象這個代碼爲什麼這個lambda函數不是打字稿中的錯誤?

let x: (a: { b: number }) => void = (a: { b: number, c: string }) => { alert(a.c) }; 
x({ b: 123 }); 

應該產生一個錯誤,因爲lambda函數需要在a參數的附加屬性,所以簽名不應該是兼容的。但在最新的打字遊樂場試用這款遊戲並不會產生任何錯誤!這是爲什麼?

+0

嚴格地說實際功能並不相符的X至於結構性打字關注類型。 – toskv

回答

0

當你說

let x: (a: { b: number }) => void

您是說「x是一個函數,它有b鍵的對象。」

然後,您爲其分配了一個帶有b密鑰和c密鑰的對象的lambda。這通過了類型檢查器,因爲任何傳入的對象都必須有一個b鍵。

然後你通過它一個b鍵的對象。沒有錯誤。

如果你希望它失敗,因爲c鍵,使x的類型如下:

let x: (a: { b: number, c: string }) => void

+0

對不起,但我仍然不知道*爲什麼這不會是錯誤。需要一個c鍵的lambda不能通過一個b鍵傳遞一個對象,那麼如何將它分配給x的類型,它接受這個?我的想法是,參數類型是lambda可以承擔的一系列保證。將它分配給x會中斷它,所以它不應該被允許。 – Ludwik

+0

這是因爲你正在給一個精度較低的變量提供一個更精確的lambda。想象一下,如果你說'let x:Animal = new Cat()'。這顯然很好,即使'Animal'可能不具有'Cat'的所有屬性。將需要更多屬性的lambda指定給需要更少類型的變量也不是錯誤。 – thedayturns

+0

當然,這對於物體完全有意義,但是它不應該是相反的功能方式嗎?在對象中,你不能做'let x:Cat = new Animal()',但是你可以做相反的事情,因爲不管貓的具體情況如何,它都可以完成Animal的所有功能。在函數中,一個以動物作爲參數的函數'f'可以佔用一隻貓,但一個函數'g'需要一隻貓不能攜帶任何動物。換句話說,*'f'可以處理'g'的所有輸入,但不能反過來*。因此,在我看來'f = g'應該是可以接受的,但不是'g = f'。 – Ludwik