Encounter a Typescript error when dealing with "app.ws" while using express-ws

I have a small project in mind where I want to create a BabyCam that can be accessed from any web browser using a Raspberry Pi Zero. My plan is to set up a web socket using express-is to stream video to multiple clients. I'm utilizing the raspivid-stream module for most of the video-related code. However, when attempting to access the web socket, I encounter a type error related to app.ws(..., specifically stating

Property 'ws' does not exist on type 'Application'
. I've made sure to import the typings for both express and express-ws.

I'm somewhat confused as to why this problem is occurring, especially since the same call works fine in JavaScript. Here's the code snippet - any help would be greatly appreciated!

import express from 'express';
import { Request, Response } from 'express';
import fs from 'fs';
import https from 'https';
import http from 'http';
import raspividStream from 'raspivid-stream';
import expressWs from 'express-ws';


const server: express.Application = express();

const httpPort: number = 8080;
const httpsPort: number = 8443;

const sslCredentials = {
    key: fs.readFileSync('../ssl/localhost.key', 'utf8'),
    cert: fs.readFileSync('../ssl/localhost.cert', 'utf8')
};

// CREATE SERVER

const httpServer = http.createServer(server);
const httpsServer = https.createServer(sslCredentials, server);

expressWs(server, httpsServer);

// ROUTES

server.get('*', (req: Request, res:Response) => {
    if (!req.secure) {
        return res.redirect(`https://${req.hostname}:${httpsPort}${req.originalUrl}`);
    }
    res.sendFile(__dirname + '/client/index.html');
});

// WEBSOCKET

server.ws('/video-stream', (ws) => {
    console.log('Client connected');


    ws.send(JSON.stringify({
    action: 'init',
    width: '960',
    height: '540'
    }));

    var videoStream = raspividStream({ rotation: 180 });

    videoStream.on('data', (data) => {
        ws.send(data, { binary: true }, (error) => { if (error) console.error(error); });
    });

    ws.on('close', () => {
        console.log('Client left');
        videoStream.removeAllListeners('data');
    });
});


// START SERVER

httpServer.listen(httpPort, () => {
    console.log(`BabyCam (redirect) listening at http://localhost:${httpPort}/`);
}); 

httpsServer.listen(httpsPort, () => {
    console.log(`BabyCam (SSL) listening at https://localhost:${httpsPort}/`);
});

Answer №1

Issue with 'ws' in type 'Application'
is an error specific to TypeScript, indicating that TypeScript does not recognize a method called ws() on the object app. This occurs because ws() is not part of the standard express API, and therefore the TypeScript types (@types/express) do not include it.

The ws() method is actually provided by the express-ws module as an add-on feature. The TypeScript types for express-ws (@types/ws-express) do define this method, but the code structure needs to be adjusted to ensure TypeScript recognizes it properly...

To address this issue, first make sure you have installed the TypeScript types for both express and express-ws:

npm install @types/express @types/express-ws

Next, create the server instance as shown below:

const expressServer = express();           // Type = Express 
const wsServer = expressWs(expressServer); // Type = expressWs.Instance
const server = wsServer.app;               // Type = wsExpress.Application

By defining the code in this manner, the variable server will now have the correct type of expressWs.Application, as specified here (which includes the declaration for ws() here).

It's important to note that the runtime value of server and expressServer remains the same. They both refer to the exact same Express instance (which explains why your code runs without issues when executed as regular JavaScript). The only difference lies in how TypeScript handles the type information.

Answer №2

The object Express.Application does not contain an attribute named ws, which is causing the error message to be displayed. In order to resolve this issue, you should utilize the result of expressWS(server, httpsServer) as the app variable that is accessible, typed as Express.Application & WithWebsocketMethod.

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

How can Express be used to host static content on a subdomain?

I have an express app and I've added code to serve static content from the docs/public directory. However, the static content is being served to the root of my application instead of a subdomain or subdirectory like blog.mydomain.com or mydomain.com/b ...

Is there a method to consistently transmit certain information to the rendering engine?

As I work on my project using Express.js and Jade, I've come to realize the need to pass a user object to Jade every time: var renderObject = { navigation: [{ url: "/",   title: "Home" }], user: user } res.render('MyTe ...

How can a fixed type value be assigned to a portion of a type that is constrained by generics?

Experience a new aspect of Ids with my basic interface: interface Identifiable { id?: number; } Behold, a universal function that transforms record objects into entities with ids: function transformRowToObject<T extends Identifiable>(row: { id: ...

What are the conditions for Jasmine's .toHaveBeenCalledWith to match the parameters?

I'm working on an Angular service along with its Jasmine test. The test is calling f1() and spying on f2(). The function f2 takes a variable v2 and updates it by setting field 'a' to 3. I expected the function f2 to be called with v2 (as def ...

Sending an empty data structure to the database

I am currently working on developing a basic search feature to query a postgresql database. While running the function and monitoring with console logs, I have noticed that it is returning a 200 status code, but the object being sent is blank. Below you ca ...

The React context hooks are failing to update all references

In my project, I am working on setting up a modal with a custom close callback. To achieve this, I used a useState hook to store the method and execute it within an already defined function called closeModal(). However, I encountered an issue when attempt ...

Mapping an array of keys to an array of properties using Typescript

Is there a way to achieve the following: type A = { a: string; b: number; c: boolean }; type B = ["b", "a"]; type C = MapProps<A, B> ?? // [number, string] The solution I have currently is: type C = {[key in B[number]]: A[key]} ...

NextJS introduces a unique functionality to Typescript's non-null assertion behavior

As per the typescript definition, the use of the non-null assertion operator is not supposed to impact execution. However, I have encountered a scenario where it does. I have been struggling to replicate this issue in a simpler project. In my current proj ...

Validating patterns in Angular without using a form

Seeking guidance on validating user input in Angular6 PrimeNG pInputText for a specific URL pattern, such as , possibly triggered on blur event. This particular field used to be part of a form but has since been relocated to a more complex 6-part form int ...

Having trouble retrieving data in the service. Unable to subscribe to it from other components

userService.ts private APIUrl: string = environment.APIUrl; constructor(private inService: API, private httpClient: HttpClient) { } private _userDataDashboard$ = new ReplaySubject<UserDetailsDashboard>(1); getUserDetailsSubject(): Obser ...

Res.redirect() showing unexpected behavior

In my current setup, I am utilizing a modified version of the vhost connect/express middleware. Within this middleware, there is a check for the presence of the www subdomain. If the subdomain is found, it should redirect to the host + path without the www ...

Discover the step-by-step process of leveraging require.js to define a template similar to a Vue component and establish a

When working on projects that involve express and require.js along with Vue CDN, I often encounter the need to define a template using require.js that is similar to Vue components. In my index.js file, I have a data list that I want to display in the inde ...

What steps should I take to plan a collaborative code-sharing project?

As I develop various applications utilizing a core framework of my own creation, I am looking for a way to easily manage updates across all these applications. I have structured the code by creating a GitHub project where the main branch consists of the co ...

Using multer for file upload causes React application to refresh

Important Update: The issue I am facing is related to hot-reloading in Creact React App. For more information, check out the following links: https://github.com/expressjs/multer/issues/566 https://github.com/facebook/create-react-app/issues/4095 I am del ...

There was a TypeScript error found at line 313, character 9 in the file @mui/material/styles/experimental_extendTheme.d

Encountering Typescript error while using Material UI component for date range picker Link - https://mui.com/x/react-date-pickers/date-range-picker/ Snippet of the code import * as React from 'react'; import { Dayjs } from 'dayjs'; im ...

Trouble extracting and utilizing GraphQL queries in Typescript with relay-compiler

I attempted to utilize relay with the Typescript react starter, but I am encountering several problems. It appears that babel-plugin-relay is unable to detect the graphql statements extracted by the relay-compiler. Below is my compiler script: "relay": " ...

Ensuring Compliance with GDPR through Cookie Consent Logic

Since the introduction of GDPR, I find myself in need of clarity on the steps to take both server-side and client-side to ensure compliance. Apologies for the plethora of questions. I currently have a first-party cookie that is used to store a session coo ...

The name '__DEV__' is not discoverable at the moment

While working with the mobx library in my project, I encountered an issue after installing it using npm. Upon exploring the mobx/src/error.ts file within the node_modules folder, I came across a compile time error on line 78: const errors: typeof niceError ...

Having issues with @ts-ignore in Typescript on a let variable that is not reassigned?

JOURNEY TO THE PROBLEM My current task involves destructuring a response obtained from an Apollo useLazyQuery, with the intention to modify one variable. In a non-Typescript environment, achieving this would be straightforward with just two lines of code: ...

Troubleshooting Issues with https.request and Options in NodeJS Leading to Connection Resets

When working with NodeJS, I noticed that my code performs as expected when using https.get() to retrieve responses. However, the moment I make the switch to https.request() along with requestOptions, I encounter a connection reset error along with the foll ...