I'm trying to promisify standard node fs.writeFile. I have typings for both node and bluebird which is my Promise lib of choice here:
const f = Promise.promisify(fs.writeFile)
return f(file, content); // Should be a promise
This does not work because:
[ts] Supplied parameters do not match any signature of call target. const f: (arg1: string) => Promise<{}>
So i chooses the wrong overloaded method because the call to promisify can't really know which I guess. Or maybe it's not even that, but something with the optional arguments, because these are the three overloaded writeFile:
export function writeFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void;
export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void;
export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void;
promisify has lots of overloads for # of args and looks like this:
/**
* Returns a function that will wrap the given `nodeFunction`. Instead of taking a callback, the returned function will return a promise whose fate is decided by the callback behavior of the given node function. The node function should conform to node.js convention of accepting a callback as last argument and calling that callback with error as the first argument and success value on the second argument.
*
* If the `nodeFunction` calls its callback with multiple success values, the fulfillment value will be an array of them.
*
* If you pass a `receiver`, the `nodeFunction` will be called as a method on the `receiver`.
*/
static promisify<T>(func: (callback: (err:any, result: T) => void) => void, receiver?: any): () => Promise<T>;
static promisify<T, A1>(func: (arg1: A1, callback: (err: any, result: T) => void) => void, receiver?: any): (arg1: A1) => Promise<T>;
static promisify<T, A1, A2>(func: (arg1: A1, arg2: A2, callback: (err: any, result: T) => void) => void, receiver?: any): (arg1: A1, arg2: A2) => Promise<T>;
static promisify<T, A1, A2, A3>(func: (arg1: A1, arg2: A2, arg3: A3, callback: (err: any, result: T) => void) => void, receiver?: any): (arg1: A1, arg2: A2, arg3: A3) => Promise<T>;
static promisify<T, A1, A2, A3, A4>(func: (arg1: A1, arg2: A2, arg3: A3, arg4: A4, callback: (err: any, result: T) => void) => void, receiver?: any): (arg1: A1, arg2: A2, arg3: A3, arg4: A4) => Promise<T>;
static promisify<T, A1, A2, A3, A4, A5>(func: (arg1: A1, arg2: A2, arg3: A3, arg4: A4, arg5: A5, callback: (err: any, result: T) => void) => void, receiver?: any): (arg1: A1, arg2: A2, arg3: A3, arg4: A4, arg5: A5) => Promise<T>;
static promisify(nodeFunction: Function, receiver?: any): Function;
So it seems it rather the wrong promisify that is being used. Is there any cleaner way for me to achieve what I want? Currently I have to resolve to this:
const writeFile : (filename: string, data: any, callback: (err: NodeJS.ErrnoException) => void) => void = fs.writeFile
const f = Promise.promisify(writeFile)
return f(file, content);
which I feel is very ugly and verbose…
you could use __promisify__
from fs.writeFile
namespace:
fs.writeFile.__promisify__(file, content)
Otherwise, you've to explicitly mention generic types to pick corresponding overload:
util
package has a promisify()
functionconst f = util.promisify<PathLike, string, void>(fs.writeFile)
f(file, content)
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