Home > Back-end >  how do I strongly type socketIO server in typescript
how do I strongly type socketIO server in typescript

Time:01-09

How do I strongly type the private property private io to stop Typescript from throwing this error Property 'io' has no initializer and is not definitely assigned in the constructor

import fastify, { FastifyReply, FastifyRequest } from "fastify";
import socketIO from "socket.io";
import fastifysocketIO from "fastify-socket.io";
import fastifyStatic from "fastify-static";
import path from "path"



class App {
    private server;
    private port: number;
    private io: socketIO.Server;

    constructor(port: number) {
        this.server = fastify({ logger: true });
        this.port = port;
        this.server.register(fastifyStatic, {

            root: path.join(__dirname, "../public"),
        });
        this.server.register(fastifysocketIO, ({
            cors: { origin: "*" }
        }));

        this.server.ready(err => {
            if (err) { throw err }
            this.io = this.server.io;

            this.io.on('connect', (socket: socketIO.Socket) => {
                return console.info('Socket connected!', socket.id);
            })
        });

        this.server.get("/", (request: FastifyRequest, reply: FastifyReply) => {
            reply.sendFile("chat.html");
        })
    }
    public start() {
        this.server.listen(this.port);

    }
}
new App(3000).start();

CodePudding user response:

You're setting .io in a callback, potentially after the server has started. You have 3 options:

Ignore the error

If you specify your property as:

private io!: socketIO.Server;

it tells Typescript: I know I'm not setting this property during construction, but 'trust me it's fine'.

But just as a reminder, there is a small window between constructing your App class and the ready callback where this.io is undefined.

Accurately type

You can change the definition to:

private io: socketIO.Server | null = null;

This forces every use of this.io to first ensure that it's initialized.

Set everything up before construction.

The short version of this is, you can also construct your Server and IO objects outside the class and pass it as arguments in the constructor.

This is more of a subjective observation, but I see a lot of folks writing Javascript when they are coming from other programming languages where there's classes for everything (Like Java and PHP), even when there's no need.

Classes should be use sparingly in Javascript, and should have a purpose. They are often harder to type with Typescript if they have an 'evolving state' like this.

If this is your entire class, I personally think this has no business being a class.

  •  Tags:  
  • Related