[英]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.