ts-reset
ts-reset copied to clipboard
Use `JsonValue` as `JSON.parse` Return Type?
Perhaps this would go further that what is wanted from this library, but I think it'd be nice if JSON.parse could return a type similar to (or the same as) JsonValue from type-fest (see https://github.com/sindresorhus/type-fest#json).
I've never used the optional reviver function in JSON.parse, but it looks like it can modify the return type beyond JsonValue, so perhaps it'd make sense to have a return type of JsonValue if no reviver is passed, then unknown if a reviver is passed?
I think unknown here is safer, but I'll leave this issue open!
interface JSON {
parse<T = unknown>(
text: string,
reviver?: (this: any, key: string, value: any) => any,
): T;
}
@j if the aim is type safety, that isn't safe
@j Hiding this as not relevant to the issue. Please also take a look at the readme, where I mention in detail the reason why we won't be implementing this.
@mattpocock
true; understood. I live in a world where I consume self-owned APIs and messages that are type-safe at the point of having to parse it, so my brain went there.
with that said, leaving as unknown and forcing narrowing or casting is better.
Same applies to JSON.stringify:reviver btw ^.^
I'd like to see JsonValue when no reviver too. I can't see how it's less safe?
OK - I think I prefer unknown here instead of JSONValue. The reason is that narrowing based on unknown is actually more productive. With JSONValue you actually lose a lot of value in the return type, preventing you from narrowing properly:
https://tsplay.dev/WKpQKw
I created a PR, #123, for a type-safe and sound version of JSON.parse if anybody is interested. I also wrote a good description of the problem statement and the solution that I implemented.
@mattpocock Consider the following playground example. With noUncheckedIndexedAccess you can see that the type of result.whatever is just JsonValue, but the type of result.awdkjanwdkjn is JsonValue | undefined. You may not get autocomplete for whatever and an error for awdkjanwdkjn, but this is the next best thing.