如何修复TS2349错误:该表达式不可调用
你的代码:
window.addEventListener('message', (event) => { event.source.postMessage("response",event.origin) });
触发的错误:
TS2349: This expression is not callable.
Each member of the union type '((message: any, targetOrigin: string, transfer?: Transferable[]) => void) | { (message: any, transfer: Transferable[]): void; (message: any, options?: PostMessageOptions): void; } | { ...; }' has signatures, but none of those signatures are compatible with each other.
两种解决办法:
1. 明确断言event.source为Window类型
event.source的类型是MessageEventSource,包含了Window、MessagePort、ServiceWorker等可能,只有Window的postMessage支持直接传targetOrigin字符串。先判断不为null,再做类型断言:
window.addEventListener('message', (event) => { if (event.source) { (event.source as Window).postMessage("response", event.origin); } });
2. 使用PostMessageOptions参数(更通用)
这种写法兼容所有MessageEventSource的实现,不用做类型断言:
window.addEventListener('message', (event) => { event.source?.postMessage("response", { targetOrigin: event.origin }); });
错误原因
event.source是联合类型,不同成员的postMessage签名不统一:
- Window的postMessage支持
(message, targetOrigin, transfer?)的参数形式 - MessagePort/ServiceWorker的postMessage则是
(message, transfer)或(message, options)的形式
直接传event.origin当第二个参数时,TypeScript无法确定匹配哪个签名,因此抛出错误。用PostMessageOptions对象可以统一适配所有情况,或者断言为Window来匹配对应的签名。
内容的提问来源于stack exchange,提问作者Pongsiril

