gcanti / fp-ts

Functional programming in TypeScript
https://gcanti.github.io/fp-ts/
MIT License
10.78k stars 502 forks source link

Why does `Json.stringify` return an `Either`? #1909

Open davezuch opened 11 months ago

davezuch commented 11 months ago

šŸš€ Feature request

Current Behavior

Json.stringify is currently defined as: https://github.com/gcanti/fp-ts/blob/01b8661f2fa594d6f2010573f010d358e6808d13/src/Json.ts#L60

Desired Behavior

Coming from PureScript, I don't expect encoding a value as JSON to fail.

Suggested Solution

It seems to me rather than trying to encode any JS value as JSON, most use cases (and I could be wrong here) will be trying to encode a value that extends Json.Json. If that's the case, stringify could pretty safely be implemented as:

const stringify = <Value extends Json>(value: Value): string => JSON.stringify(value)

Of course I could be overlooking an obvious reason that the current implementation makes more sense. But if the current implementation is necessary for some cases, while the implementation suggested here would work for most, then I think it's worth providing both.

Who does this impact? Who is this for?

Maybe just me but I assume this would benefit all users as they could avoid having to deal with failure when encoding JSON.

Your environment

Software Version(s)
fp-ts 2.16.1
TypeScript 5.1.6
DenisFrezzato commented 11 months ago

JSON.stringify throws a TypeError when the value contains a circular reference or a BigInt.

davezuch commented 11 months ago

JSON.stringify throws a TypeError when the value contains a circular reference or a BigInt.

BigInt doesn't extend Json though. And while I'm still learning TS, I can't figure out how to construct a self-referencing Json type without using any then casting it to Json with stringify(notJson as Json), which if you're doing, then you should expect type-errors anyway.

So without deliberately circumventing the compiler, you shouldn't be able to call the stringify function I suggested with either.