[英]How can I narrow down the type of a function argument without a variable
我有一個接受any
參數的 function:
declare function postMessage(message: any): void;
我正在嘗試使用某種類型的 object 來調用它,如下所示:
interface NumMsg {type: 'num'; num: number}
interface StrMsg {type: 'str'; str: string}
type Msg = NumMsg | StrMsg;
postMessage({type: 'num', num: 42} as Msg);
postMessage({type: 'str', str: 'Hello World!'} as Msg);
它有點工作,但它使一些必需的屬性成為可選的 - 它成功構建而沒有任何錯誤:
// Works fine / fails to build:
postMessage({type: 'num', 'str': 'Hello world!'} as Msg);
postMessage({type: 'str', 'num': 42} as Msg);
// Doesn't work fine / build without errors:
postMessage({});
postMessage({type: 'str'} as Msg);
postMessage({type: 'num'} as Msg);
我可以通過首先將其定義為變量來解決該問題:
let msg1: Msg = {};
let msg2: Msg = {type: 'str'};
let msg3: Msg = {type: 'num'};
我可以在不定義任何變量的情況下完成這項工作嗎?
我假設您不能更改postMessage
的類型(例如,它是在 web 平台或類似平台中定義的postMessage
)。
我會通過使用包裝器 function 來解決這個問題,而不是變量,並且根本不直接使用postMessage
:
function postMsg(message: NumMsg | StrMsg) {
postMessage(message);
}
(但有一個更好的 function 名稱。:-))
然后這些工作:
postMsg({type: "num", num: 42});
postMsg({type: "str", str: "Hellow world!"});
...並且這些會根據需要導致錯誤:
postMsg({});
postMsg({type: "str"});
postMsg({type: "num"});
postMsg({type: "num", "str": "Hello world!"});
postMsg({type: "str", "num": 42});
如果您可以更改postMessage
的類型,則直接進行:
declare function postMessage(message: NumMsg | StrMsg): void;
最后,我決定為上述function添加一個過載:()
declare function postMessage<T>(message: T): void;
感謝@jonrsharpe 。
現在我有以下內容:
declare function postMessage(message: any): void;
declare function postMessage<T>(message: T): void;
即使前一個簽名/似乎更通用,它也可以工作。
現在我可以毫無問題地執行以下操作:
postMessage<Msg>({type: 'num', 'str': 'Hello world!'});
postMessage<Msg>({type: 'str', 'num': 42});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.