-
Notifications
You must be signed in to change notification settings - Fork 12.4k
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
JSON: more general type of JSON.parse()
#48907
Comments
Duplicate of #44944. Used search terms: |
yes. In fact, I also searched for this before raising this issue, but I don't agree with it. First of all, Second, but: The first time I didn't notice, there was a very old issue linked under that issue #17203 , and although it focused on a different point than mine ( Let's pay attention to the last two comments:
and:
On the second floor, the leader of TS also has a sentence:
This may be the reason why the previous problem was not solved, so let's rethink: Should this be wrong? See MDN:
It seems that almost everyone agrees that This may be more of a conceptual issue than a technical one. Maybe we should ask the authors of sindresorhus/eslint-plugin-unicorn#1273 to discuss this, especially the author @fisker. |
Such an issue has been raised again and again, and the answer was always the same by the TypeScript team.
What do you believe will cause more issues and trouble for most developers:
I'm confident to say the first option is by far worse than the second. What you actually want is something like #35945. The ability to pass types that explicitly coerce to |
You're right, I think it touches on a deeper issue: TypeScript (or ESLint, or some other best practice) wants to make the code clearer and more intuitive, for example, we recommend using strict operators (like That said, the above principle encourages us to do more explicit work than implicit work. Continuing in this line of thought, our code might look like this: const obj = {
toString() {
return '[1, 2, 3]'
}
};
const arr = JSON.parse(String(obj)); // [1, 2, 3]
// or
const arr = JSON.parse(obj.toString()); // [1, 2, 3]
// even
const arr = JSON.parse(obj + ''); // [1, 2, 3] In this way, TypeScript will not report an error. Similar things are done for What do you think? |
FYI:I proposed |
Anyway,
Use that rule on your own judgement. |
I'd argue most people use TypeScript for type-safety to avoid bugs at design and compilation time. Accepting only |
This could be the difference between these two: // 1
import fsP from 'fs/promises';
JSON.parse(await fsP.readFile('./***.json'));
// 2
import fs from 'fs';
JSON.parse(fs.readFileSync('./***.json')); instead of: // 1-1
import fs from 'fs';
JSON.parse(fs.readFileSync('./***.json'));
// 1-2
import fs from 'fs';
JSON.parse(fs.readFileSync('./***.json'), 'utf8');
// 2-1
import fsP from 'fs/promises';
JSON.parse(await fs.readFile('./***.json'));
// 1-2
import fsP from 'fs/promises';
JSON.parse(await fs.readFile('./***.json'), 'utf8'); When I see
in https:/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/prefer-json-parse-buffer.md, I think that 1-1 (or 2-1) is slower than 1-2 (or 2-2), but I see the source code of Of course that's not the point.
I read the previous reasons why the TypeScript team objected to a request similar to mine, and realized that they didn't expect "implicit type conversions" to happen, but to pass each parameter in the most natural and intuitive way possible.
Yes, we shouldn't break the type safety that most people expect in order to take care of such an extreme case that hardly anyone uses.
If this scenario is indeed used very frequently, I think it may be a better choice to encapsulate a function: import fsP from 'fs/promises';
const readJsonFile = async (path: string) => JSON.parse(await fsP.readFile(path, 'utf8')); In order not to break type safety, I think it's worth it. |
I'm getting confused by the conversation... @dev-itsheng You opened the issue saying |
Because I was convinced by them and decided to change my original idea. In fact, I was also influenced by @fisker when I first made this point, so I @@fisker to join the discussion at the beginning. Maybe I should close this issue and let them continue the discussion? |
It seems no-one's actually in favor of allowing passing anything to |
Well, let this be the end of it. |
lib Update Request
Configuration Check
My compilation target is
ES2015
and my lib isthe default
.Missing / Incorrect Definition
JSON.parse
。Sample Code
In Node.js:
TypeScript throw a new Error
TS2345: Argument of type 'Buffer' is not assignable to parameter of type 'string'
.But it works.
Because according to the ECMAScript 5 version of the documentation,
JSON.parse()
, when executed, will first convert the incoming parameters Call theToString
internal method.And according to Node.js related code, the Buffer object will be converted to utf8 when calling
toString
string.That is, this parameter can be of any type, for example:
TypeScript still throw error:
You can also try it on TypeScript PlayGround.
I had to disable an ESLint rule for the same reason.
Documentation Link
The text was updated successfully, but these errors were encountered: