How to use "this" inside within writable.write function

Issue

I need to access some class instance data within a writable.write function. Here is a short snippit of typescript code that illustrates what I’m trying to do:

import * as socketio from 'socket.io'
import { Writable } from 'stream'

export class DataClient {
  public socket: socketio.Socket
  private writable: Writable

  constructor(socket: socketio.Socket) {
    this.socket = socket

    this.writable = new Writable({
      write: function (chunk, encoding, next) {
        this.socket.emit('data', chunk)
        next()
      }.bind(this),
    })
  }
}

I get the following error from ESLint:

any
'this' implicitly has type 'any' because it does not have a type annotation.ts(2683)
dataClient.ts(12, 14): An outer value of 'this' is shadowed by this container.

I’ve tried casting using <> and as, but that doesn’t make any difference. The actual code is more complex, but this shows the problem in the simplest case. Also, while I might be able to just reference socket (the parameter), there are other instance data items that I need to access as well that are not parameters of the constructor.

Is there a way to let TS know that "this" refers to the DataClient instance?

Solution

You should use an arrow function to represent the write method, then this will refer to the DataClient instance:

import * as socketio from "socket.io";
import { Writable } from "stream";

export class DataClient {
  public socket: socketio.Socket;
  private writable: Writable;

  constructor(socket: socketio.Socket) {
    this.socket = socket;

    this.writable = new Writable({
      write: (chunk, encoding, next) => {
        this.socket.emit("data", chunk);
        next();
      },
    });
  }
}

Another solution is to defie the function as a method of the class:

import * as socketio from "socket.io";
import { Writable } from "stream";

export class DataClient {
  public socket: socketio.Socket;
  private writable: Writable;

  constructor(socket: socketio.Socket) {
    this.socket = socket;

    this.writable = new Writable({
      write: this.writeFunc,
    });
  }

  writeFunc(chunk: any, encoding: BufferEncoding, next: any): void {
    this.socket.emit("data", chunk);
    next();
  }
}

Answered By – eogabor

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published