I am trying to use rxjs 5 to write a Node.js server in TypeScript, but I hit an error when converting fs.readFile
to its rxjs form. I expect the following code would work in TypeScript
// This is a JavaScript example from the official documentation. It should
// also work at the TypeScript envrionment.
import * as fs from 'fs';
import { Observable } from 'rxjs';
let readFileAsObservable = Observable.bindNodeCallback(fs.readFile);
// This is the line that throws the error.
let result = readFileAsObservable('./roadNames.txt', 'utf8');
result.subscribe(x => console.log(x), e => console.error(e));
However, my editor reports a TypeScript error when I add the second parameter 'utf-8'
Supplied parameters do not match any signature of call target.
I try to find a guide on how to use the fs.readFile()
in rxjs and TypeScript but there isn't much luck.
bindCallback
and bindNodeCallback
can be tricky with TypeScript, as it all depends upon how TypeScript infers the function parameters.
There is likely a better way, but this is what I do to see exactly what is being inferred: assign the observable to something totally incompatible and look closely at the effected error. For example, this:
const n: number = Observable.bindNodeCallback(fs.readFile);
will effect this error:
Type '(v1: string) => Observable<Buffer>' is not assignable to type 'number'.
So it's obvious that TypeScript is matching the path-only overload of readFile
.
In situations like this, I often use an arrow function to specify exactly which overload I want to use. For example, this:
const n: number = Observable.bindNodeCallback((
path: string,
encoding: string,
callback: (error: Error, buffer: Buffer) => void
) => fs.readFile(path, encoding, callback));
will effect this error:
Type '(v1: string, v2: string) => Observable<Buffer>' is not assignable to type 'number'.
So it's now matching the desired overload and the following will work:
let readFileAsObservable = Observable.bindNodeCallback((
path: string,
encoding: string,
callback: (error: Error, buffer: Buffer) => void
) => fs.readFile(path, encoding, callback));
let result = readFileAsObservable('./package.json', 'utf8');
result.subscribe(
buffer => console.log(buffer.toString()),
error => console.error(error)
);
To be honest i haven't found a solution, but in order to make it work, i cast it to a function.
(<Function>Rx.Observable.bindNodeCallback(fs.readFile))('./file.txt', 'utf8').subscribe();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With