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?
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();
}
}