I encountered an issue with TypeScript when attempting to post a message back to the source

Here is a snippet of my code

window.addEventListener('message', (e) => {
  e.source.postMessage('hi there, I hear you!', '*');
});

Encountered an error:

[ts] The type '((message: any, targetOrigin: string, transfer?: any[]) => void) | ((message: any, transfer?: any[]) => void)' does not have compatible call signatures.

Upon inspecting the postMessage method, it appears to belong to the window object with the following signature:

declare function postMessage(
    message: any,
    targetOrigin: string,
    transfer?: any[]
): void;

As I compare this signature to my code, they appear to match. So what could be causing the issue here?

Answer №1

e.source is classified as MessageEventSource.

type MessageEventSource = WindowProxy | MessagePort | ServiceWorker;

With the method signature you're utilizing, only WindowProxy is applicable, so you can protect it by:

window.addEventListener('message', (e) => {
  if (!(e.source instanceof MessagePort) && !(e.source instanceof ServiceWorker)) {
    e.source.postMessage('hi there, I hear you!', '*');
  }
});

Alternatively, you can inform TS that your e.source falls under type WindowProxy | Window.

Answer №2

The previously provided solution is accurate, but there is a potential risk of crashes in older web browsers that do not yet support MessagePort or ServiceWorker. One workaround is to verify the existence of MessagePort and ServiceWorker in the global scope using typeof, but this approach may not be sufficient for TypeScript's static validator and can unnecessarily complicate the condition.

Alternatively, I suggest checking against the Window object, which is supported by all browsers and helps prevent crashes in older browsers. Additionally, Event#source can sometimes be null, so this behavior is implicitly addressed in the updated condition, making it a more robust solution.

window.addEventListener('message', (e) => {
  if (!(e.source instanceof Window)) return;

  // Proceed with normal operations.
  e.source.postMessage('hi there, I hear you!', '*');
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having difficulty importing SVG files in TypeScript

When working with TypeScript (*.tsx) files, I encountered an issue where I couldn't import an SVG file using the following statement: import logo from './logo.svg'; The transpiler gave me this error message: [ts] cannot find module '. ...

How can I deploy a react-express application to Azure cloud platform?

Struggling to deploy my react-express application on Azure. The code is divided into client and server directories. Attempted deployment using Azure Static Web application but encountered failure. https://i.stack.imgur.com/ailA0.png https://i.stack.imgur.c ...

How can I ensure a function only runs after all imports have been successfully loaded in Vue 3?

Encountering an issue with importing a large quantitative variable in Vue 3. Upon running onMounted, it seems that the import process is not yet complete, resulting in an error indicating that the variable tesvar is "uninitialized". The code snippet prov ...

The headerStyle does not have any impact on the header component in React-Native

Currently diving into React-Native with Typescript and working on a project. Encountered a bug where the header color isn't changing as expected. Any help or insight would be greatly appreciated! -Viggo index.tsx import React, { Component } from & ...

Posting forms in NextJS can be optimized by utilizing onChange and keypress events for input fields

I am currently working on my first Edit/Update form within a newly created NextJs application as I am in the process of learning the framework. I seem to be facing an issue where the form constantly posts back to the server and causes the page to refresh ...

The specified file is not located within the 'rootDir' directory in the Cypress tsconfig.json file

I've encountered an issue while configuring Cypress in my Project, specifically with the typescript setup for Cypress. Here is the structure of my project: fronend/ - cypress/ -tsconfig.json - src/ - tsconfig.json - package.jso ...

Managing asset paths post ng build: A guide

I've been attempting to use assets to display svg icons on my ESRI map. I'm working with Angular9 and the esri js api, trying to add a symbol from a URL. Locally, the svg appears on the map, but once I build and deploy the project to IIS, it sta ...

Encountering difficulty using a template file as a component template within the Liferay angular portlet

Encountering trouble using a template file as a template for the component in my Liferay angular portlet. It works fine with a regular Angular application. app.component.ts import { Component } from '@angular/core'; @Component({ templateUr ...

Updating and saving data in Ag-Grid with server communication

Is it possible to create a grid using Ag-Grid on Angular that fetches data from a local JSON file? And how can the edited row data be saved and sent to the server or back to the local JSON file? In summary, I would like to know how to save edited row data ...

What is causing my function to execute twice in all of my components?

One issue I am facing is that I have created three different components with routing. However, when I open these components, they seem to loop twice every time. What could be causing this behavior and how can I resolve it? For instance, in one of the comp ...

Limit the range of potential inputs for the function parameter

class Coordinate { constructor(readonly x: number, readonly y: number) {} } const Up = new Coordinate(0, -1); const Right = new Coordinate(1, 0); const Down = new Coordinate(0, 1); const Left = new Coordinate(-1, 0); // How can we restrict the directio ...

AngularJS 2: Modifications to templates or components do not automatically reflect in the user interface

My background is in Angular 1, where everything worked seamlessly. However, I am encountering serious issues trying to create a basic application using Angular 2 in Visual Studio. After carefully following the "5 minute tutorial" and getting it to work, I ...

Having trouble with VSCode/tsconfig path configurations, as the files are being fetched but still receiving a "Module not found" error in the editor

Since I began working on this project, I've been encountering a peculiar issue. When importing modules and files in my Angular components/classes using import, I face an error in VSCode when the paths use the base path symbol @. Strangely enough, desp ...

Strange occurrences with HTML image tags

I am facing an issue with my React project where I am using icons inside img tags. The icons appear too big, so I tried adjusting their width, but this is affecting the width of other elements as well. Here are some screenshots to illustrate: The icon wit ...

"Trouble with Typescript's 'keyof' not recognizing 'any' as a constraint

These are the current definitions I have on hand: interface Action<T extends string, P> { type: T; payload: P; } type ActionDefinitions = { setNumber: number; setString: string; } type ActionCreator<A extends keyof ActionDefinitions> ...

Issue encountered while trying to determine the Angular version due to errors in the development packages

My ng command is displaying the following version details: Angular CLI: 10.2.0 Node: 12.16.3 OS: win32 x64 Angular: <error> ... animations, cdk, common, compiler, compiler-cli, core, forms ... language-service, material, platform-browser ... platfor ...

The instantiation of generic types in Typescript

I have been working on a function that aims to create an instance of a specified type with nested properties, if applicable. This is the approach I have come up with so far. export function InitializeDefaultModelObject<T extends object> (): T { ...

"Exploring the methods to retrieve Firebase authentication error details and outputting the console log message along with

When I encounter an error in Firebase authentication, I want to display it in the console log. However, nothing is being logged and the catch block is not even getting executed. I am unsure about why this is happening and how to retrieve the error code and ...

How can you personalize the dropdown button in dx-toolbar using DevExtreme?

Currently, I am working with the DevExtreme(v20.1.4) toolbar component within Angular(v8.2.14). However, when implementing a dx-toolbar and specifying locateInMenu="always" for the toolbar items, a dropdown button featuring the dx-icon-overflow i ...

merging pictures using angular 4

Is there a way in Angular to merge two images together, like combining images 1 and 2 to create image 3 as shown in this demonstration? View the demo image ...