繁体   English   中英

如何在没有变量的情况下缩小 function 参数的类型

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM