Skip to content

fix(std/node): fix readFile types, add encoding types: fix #6450 #6451

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 24, 2020

Conversation

balupton
Copy link
Contributor

@balupton balupton commented Jun 23, 2020

This PR corrects the node readFile types. See #6450 for the bug report. It is ready for review and at your discretion merging.

In short:

  1. the promised readFile will either reject with an error, or resolve with the data - there will never be a case where they are both null | undefined
  2. the promise, callback, and sync readFiles will return/resolve a string if a string encoding was provided, or a buffer if a binary encoding (or no encoding) was provided

This PR corrects these issues, and includes new type information for binary and text encodings such that methods can be overloaded accordingly to resolve the correct types depending on the inputs.

There was also another issue, where there was an encoding type buffer defined, however that does not exist in Node.js, and I couldn't find any usages of it within Deno either. It seemed it was meant to be binary (an encoding that returns a Buffer instance), so I changed it accordingly and added a comment.

promises.readFile

node

echo 'hello' > ../world.txt
node --input-type=module -e "import { promises as fsPromises } from 'fs'; (async () => { const str = await fsPromises.readFile('../world.txt', 'utf8'); console.log(str) })()"
hello

deno before

echo 'hello' > ../world.txt
deno eval -T "import { promises as fsPromises } from 'https://deno.land/std/node/fs.ts'; const str: string = await fsPromises.readFile('../world.txt', 'utf8'); console.log(str)"
Compile file:///Users/balupton/Projects/active/deno/__$deno$eval.ts
error: TS2322 [ERROR]: Type 'MaybeEmpty<string | Uint8Array>' is not assignable to type 'string'.
  Type 'undefined' is not assignable to type 'string'.
    at file:///Users/balupton/Projects/active/deno/__$deno$eval.ts:1:82

deno after

echo 'hello' > ../world.txt
deno eval -T "import { promises as fsPromises } from './std/node/fs.ts'; const str: string = await fsPromises.readFile('../world.txt', 'utf8'); console.log(str)"
Compile file:///Users/balupton/Projects/active/deno/__$deno$eval.ts
hello

readFile

node

echo 'hello' > ../world.txt
node --input-type=module -e "import { readFile } from 'fs'; readFile('../world.txt', 'utf8', (err, str) => console.log(err, str) )"
null hello

deno before

echo 'hello' > ../world.txt
deno eval -T "import { readFile } from 'https://deno.land/std/node/fs.ts'; readFile('../world.txt', 'utf8', (err, str: string) => console.log(err, str) )"
Compile file:///Users/balupton/Projects/active/deno/__$deno$eval.ts
error: TS2345 [ERROR]: Argument of type '(err: Error | null | undefined, str?: string | undefined) => void' is not assignable to parameter of type 'ReadFileCallback'.
  Types of parameters 'str' and 'data' are incompatible.
    Type 'MaybeEmpty<string | Buffer>' is not assignable to type 'string | undefined'.
      Type 'null' is not assignable to type 'string | undefined'.
import { readFile } from 'https://deno.land/std/node/fs.ts'; readFile('../world.txt', 'utf8', (err, str?: string) => console.log(err, str) )
                                                                                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    at file:///Users/balupton/Projects/active/deno/__$deno$eval.ts:1:95

deno after

echo 'hello' > ../world.txt
deno eval -T "import { readFile } from './std/node/fs.ts'; readFile('../world.txt', 'utf8', (err, str?: string) => console.log(err, str) )"
Compile file:///Users/balupton/Projects/active/deno/__$deno$eval.ts
null hello

readFileSync

node

echo 'hello' > ../world.txt
node --input-type=module -e "import { readFileSync } from 'fs'; const str = readFileSync('../world.txt', 'utf8'); console.log(str)"
hello

deno before

echo 'hello' > ../world.txt
deno eval -T "import { readFileSync } from 'https://deno.land/std/node/fs.ts'; const str: string = readFileSync('../world.txt', 'utf8'); console.log(str)"
Compile file:///Users/balupton/Projects/active/deno/__$deno$eval.ts
error: TS2322 [ERROR]: Type 'string | Buffer' is not assignable to type 'string'.
  Type 'Buffer' is not assignable to type 'string'.
import { readFileSync } from 'https://deno.land/std/node/fs.ts'; const str: string = readFileSync('../world.txt', 'utf8'); console.log(str)
                                                                       ~~~
    at file:///Users/balupton/Projects/active/deno/__$deno$eval.ts:1:72

deno after

echo 'hello' > ../world.txt
deno eval -T "import { readFileSync } from './std/node/fs.ts'; const str: string = readFileSync('../world.txt', 'utf8'); console.log(str)"
Compile file:///Users/balupton/Projects/active/deno/__$deno$eval.ts
hello

Tests have been updated accordingly. Static type checks in the tests capture this.

@balupton balupton marked this pull request as draft June 23, 2020 23:56
@balupton balupton changed the title fix(std/node): correct readFile types: fix #6450 fix(std/node): fix readFile types, add encoding types: fix #6450 Jun 24, 2020
}
const buffer = maybeDecode(data, encoding);
(cb as BinaryCallback)(null, buffer);
}).catch((err) => cb && cb(err));
Copy link
Contributor Author

@balupton balupton Jun 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could be changed from }).catch((err) => cb && cb(err)); to }).catch((err) => cb!(err)); as for some reason, the type checker is not considering the if statement - if it is the type checker's fault, I can do the change

@balupton balupton marked this pull request as ready for review June 24, 2020 01:57
Copy link
Member

@ry ry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - thanks!

@ry ry merged commit 49c54c0 into denoland:master Jun 24, 2020
caspervonb pushed a commit to caspervonb/deno_std that referenced this pull request Jan 21, 2021
caspervonb pushed a commit to caspervonb/deno_std that referenced this pull request Jan 24, 2021
caspervonb pushed a commit to caspervonb/deno_std that referenced this pull request Jan 24, 2021
caspervonb pushed a commit to caspervonb/deno_std that referenced this pull request Jan 24, 2021
caspervonb pushed a commit to caspervonb/deno_std that referenced this pull request Jan 31, 2021
caspervonb pushed a commit to caspervonb/deno_std that referenced this pull request Jan 31, 2021
caspervonb pushed a commit to caspervonb/deno_std that referenced this pull request Jan 31, 2021
caspervonb pushed a commit to caspervonb/deno_std that referenced this pull request Jan 31, 2021
caspervonb pushed a commit to caspervonb/deno_std that referenced this pull request Feb 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants