4

I'm trying to use fs.readFile with typescript like this...

import {readFile} from 'fs';
let str = await readFile('my.file', 'utf8');

It results in this error:

TS2345: Argument of type '"utf8"' is not assignable to parameter of type '(err: ErrnoException, data: Buffer) => void'

I'm using Typescript 2.5.2, and @types/node 8.0.30

Drahcir
  • 11,772
  • 24
  • 86
  • 128
  • 3
    I don't know about your typeScript error, but you can't do `await readFile(...)` because `readFile()` does not return a promise. `await` only works with functions that return a promise. – jfriend00 Sep 25 '17 at 11:19
  • @jfriend00 Thanks for the heads up, didn't get that far yet. I did wonder but couldn't find the docs for async await. – Drahcir Sep 25 '17 at 11:20
  • There are hundreds of articles on the web on using async and await in Javascript. You will need to read to learn how they work. You can start here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await – jfriend00 Sep 25 '17 at 11:23

4 Answers4

2

"await" is for Promises not for callbacks. Node 8.5.0 supports promisify from scratch. Use

const util = require('util');
const fs = require('fs');
const asyncReadFile = util.promisify(fs.read); 

let str = await asyncReadFile('my.file', 'utf8');
//OR
asyncReadFile('my.file', 'utf8').then( (str) => {
...
})

Happy Coding!

Parav01d
  • 308
  • 2
  • 5
  • it looks promising, but when I do it this way the application freezes on this point an does not even throw an error – Macilias Nov 22 '19 at 16:34
  • @Macilias Not easy to say why. Maybe your file is really large. In cause of errors you can try-catch the await block or use .catch(e => {...}) in the promise syntax. – Parav01d Nov 24 '19 at 16:32
  • I did try it, and documented it here: https://stackoverflow.com/questions/59028704/how-to-read-json-file-with-react-native-fs Its a mass – Macilias Nov 25 '19 at 09:32
1

The 3rd argument can only be a string (encoding) when the 3rd is a callback, see the signature in the type definitions:

export function readFile(path: PathLike | number, options: { encoding: string; flag?: string; } | string, callback: (err: NodeJS.ErrnoException, data: string) => void): void;

So by adding a callback it will work:

readFile('my.file', 'utf8', () => {

});

Or use a promisification library to generate the callback and use with await:

let str = promisify('my.file', 'utf8');
Drahcir
  • 11,772
  • 24
  • 86
  • 128
1

I'm using Typescript 4.2 and 'fs/promises'. I had the same problem. This worked

import * as fsp from 'fs/promises'
await fsp.writeFile(filename, data,'utf-8' as BufferEncoding)

We can find in the file .../node_modules/@types/node/globals.d.ts the definition for BufferEncoding:

// Buffer class
type BufferEncoding = "ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "latin1" | "binary" | "hex";

So "utf-8" (or some other valid string) is correct, but the typescript compiler needs a nudge to figure it out. Typescript is hard, even for the compiler.

Craig Hicks
  • 2,199
  • 20
  • 35
  • 1
    I had a similar error, TS needed a nudge to read the path as a string instead of a Buffer. I used `{ encoding: 'utf-8' }` for the options – myol Jun 21 '21 at 09:11
0

Promisify didn't work in my case either. I managed similar task finally by ensuring that the file has been saved with 'utf8' encoding and the following way to read it:

let asset_content = null;
try {
    await RNFetchBlob.fs.readFile(assetFile_path, 'utf8')
      .then((data) => {
        asset_content = data;
        console.log("got data: ", data);
      })
      .catch((e) => {
        console.error("got error: ", e);
      })
  } catch (err) {
    console.log('ERROR:', err);
}
const assets = JSON.parse(asset_content);
Macilias
  • 3,279
  • 2
  • 31
  • 43