Skip to content
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

Lib type definition for JSON.stringify asserts incorrect return type #55436

Closed
rewento opened this issue Aug 19, 2023 · 2 comments
Closed

Lib type definition for JSON.stringify asserts incorrect return type #55436

rewento opened this issue Aug 19, 2023 · 2 comments

Comments

@rewento
Copy link

rewento commented Aug 19, 2023

⚙ Compilation target

ES2022

⚙ Library

es2022

Missing / Incorrect Definition

ECMA-262 2011 (5.1) indicates that the value returned by a call of the JSON.stringify method may be a string or undefined. See Step 11 of the "abstract operation Str(key, holder)" outlined here in the specification.

ECMA-262 2022 (13) indicates the same. See Note #5 under the specification's JSON.stringify section.

Mozilla Developer Network documentation reiterates the same: "JSON.stringify() can return undefined when passing in "pure" values like JSON.stringify(() => {}) or JSON.stringify(undefined)".

According to the aforementioned specifications and documentation, this is the union type that includes all values that, when supplied as the first argument in a call of JSON.stringify, elicit an undefined return value: Function | Symbol | undefined.

Executing these statements in any JavaScript runtime environment confirms JavaScript engine adherence to the behavior of JSON.stringify described in the specifications and documentation:

JSON.stringify(undefined); // Returns undefined.
JSON.stringify(function() {}); // Returns undefined.
JSON.stringify(() => {}); // Returns undefined.
JSON.stringify(Symbol()); // Returns undefined.

However, the JSON interface included among the TypeScript lib type definitions asserts that a call of the stringify method will return a value of type string in all cases and never an undefined value.

interface JSON {
    // ...
    // Neither signature includes undefined in its return type.
    stringify(value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string;
    stringify(value: any, replacer?: (number | string)[] | null, space?: string | number): string;
}

The JSON interface should be modified so that its signatures for the stringify method acknowledge the cases in which the method may return undefiend as well as the cases in which it will return undefined. For example:

interface JSON {
    // ...
    // Will return an undefined value.
    stringify(value: Function | Symbol | undefined, replacer?: (this: any, key: string, value: any) => any, space?: string | number): undefined;
    // Will return either a string or undefined.
    stringify(value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string | undefined;
    // Will return an undefined value.
    stringify(value: Function | Symbol | undefined, replacer?: (number | string)[] | null, space?: string | number): undefined;
   // Will return either a string or undefined.
    stringify(value: any, replacer?: (number | string)[] | null, space?: string | number): string | undefined;
}

Sample Code

// Type of example variables reported by TypeScript compiler is string, which is inaccurate. The correct type is undefined.
const example1 = JSON.stringify(function(){});
const example2 = JSON.stringify(() => {});
const example3 = JSON.stringify(Symbol());
const example4 = JSON.stringify(undefined);

// Playground: https://www.typescriptlang.org/play?ts=5.3.0-dev.20230819#code/PTAEBUE8AcFNQPYDNSwB4EMC20A28A3DAJwEsMAjfAZ1GNmgWIBdYATUCyCGWAZQDGZaM1ACEOUvmKhStaszIA7AOYAaUAHcAFqQHbZtUkowCBAV2IZWAOgjb444vQGjmvQ6HNK2sJMfYbAChxJQVUTBx8AEZQAF5QACk+AHkAORsFZRVSJEgACiRvV1IEJXyASgBvAF8KgG4QsvD0bDxYACZ4pNSMrOMcvPzK+IA+UFqGprDRVqjYAGZu5PTMxQHcgr5ILAoEXEqp0JbI9oAWZd617M38719-JXYpoKA

Documentation Link

ECMA-262 2022 Section 15.12.3

Mozilla Developer Network documentation of JSON.stringify.

@MartinJohns
Copy link
Contributor

MartinJohns commented Aug 19, 2023

Duplicate of #18879 and many others. This is intentional. See this comment: #18879 (comment)

@rewento
Copy link
Author

rewento commented Aug 19, 2023

Sorry, @MartinJohns. I forgot to remove the "is:open" filter when searching for existing issues regarding this matter. I'll make sure to do that before creating new issues.

@rewento rewento closed this as completed Aug 19, 2023
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

No branches or pull requests

2 participants