-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Update JSON.stringify #29744
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
Update JSON.stringify #29744
Conversation
To ban the the input value 'undefined' passing in undefined returns undefined. Therefore making the return type incorrect. We could also add an overload for a type that takes undefined and returns undefined but that's redundant anyway. NOTE: functions aren't allowed to be inputs either, but I don't know how to not allow functions but allow all other functions in Typescript.
It looks like you've sent a pull request to update our 'lib' files. These files aren't meant to be edited by hand, as they consist of last-known good states of the compiler and are generated from 'src'. Unless this is necessary, consider closing the pull request and sending a separate PR to update 'src'. |
Looked at some of the failing tests and they are legitimate problems that need to be fixed. JSON.stringify should not be called with undefined. I'll need help fixing those issues, or I can just close this PR and someone else can pick this up. |
@@ -1043,14 +1043,14 @@ interface JSON { | |||
* @param replacer A function that transforms the results. | |||
* @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read. | |||
*/ | |||
stringify(value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string; | |||
stringify(value: Object | string | number | boolean | symbol | null, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: JSON.stringify(Symbol.for('foo')) === undefined
, so symbol
should be dropped
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
problem is return type from stringify not allowed value types. I think it should be undefined | string instead. This can be addressed by adding specific overloads. Please correct me if I am wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
string | undefined
with --strictNullChecks
would force you make an existential check at runtime, even when it's statically provable what the return type would be
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but not when you have overloads.
stringify(value: Object | string | number | boolean | null, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string;
stringify(value: undefined | Function | symbol, replacer?: (this: any, key: string, value: any) => any, space?: string | number): undefined;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i misunderstood; based on the type signature you wrote i thought you were advocating for a single api. my apologies!
you are correct, an overloaded api would be strictly better. i checked your definitions against MDN and they look correct too.
thank you :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't it be object
instead of Object
?
And it would useful to move this into a JSONStringifyable
type so it can be reused.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you're correct; object
narrows out symbol
where Object
does not:
declare class Foo {
foo(o: object): boolean;
foo(o: symbol | Function): string;
}
new Foo().foo(Symbol.for('')); // string
declare class Bar {
bar(o: Object): boolean;
bar(o: symbol | Function): string;
}
new Bar().bar(Symbol.for('')); // boolean
unfortunately, i found a different issue:
new Foo().foo(() => { }); // boolean, should be string
new Bar().bar(() => { }); // boolean, should be string
this would be most readily resolved by moving the overload with Function
above the "happy path" overload. unsure if that's the right decision or if there's an alternative i'm missing.
/** | ||
* Converts a JavaScript value to a JavaScript Object Notation (JSON) string. | ||
* @param value A JavaScript value, usually an object or array, to be converted. | ||
* @param replacer An array of strings and numbers that acts as a approved list for selecting the object properties that will be stringified. | ||
* @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read. | ||
*/ | ||
stringify(value: any, replacer?: (number | string)[] | null, space?: string | number): string; | ||
stringify(value: Object | string | number | boolean | symbol | null, replacer?: (number | string)[] | null, space?: string | number): string; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see above
What issue is tracking this change? |
@RyanCavanaugh #18879, though i'm pretty sure OP came from this tweet |
Haven't forgotten, I'll make the change to remove symbol from the list and try and fix the failing tests. |
Closing due to long-term CI failure See also comments in #29962 (comment) if anyone wants to open a fresh PR |
To ban the the input value 'undefined' passing in undefined returns undefined. Therefore making the return type incorrect.
We could also add an overload for a type that takes undefined and returns undefined but that's redundant anyway.
NOTE: functions aren't allowed to be inputs either, but I don't know how to not allow functions but allow all other functions in Typescript.
Fixes #