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

Make JsonObject work as expected with TS 4.4 --exactOptionalPropertyTypes #272

Closed
voxpelli opened this issue Sep 22, 2021 · 3 comments · Fixed by #465
Closed

Make JsonObject work as expected with TS 4.4 --exactOptionalPropertyTypes #272

voxpelli opened this issue Sep 22, 2021 · 3 comments · Fixed by #465
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@voxpelli
Copy link
Collaborator

voxpelli commented Sep 22, 2021

#269 brought to my attention that #65 changed the JsonObject so that all keys are marked as optional.

Before TypeScript 4.4 a { foo?: string} and a { foo?: string|undefined } was always treated as equal, so #65 made sense then.

But with TS 4.4 the new --exactOptionalPropertyTypes config was introduced, which (correctly )no longer treats { foo?: string} as equal to { foo?: string|undefined }.

For some reason though, the change introduced in #65 still gets treated in the old way:

export type JsonObject = {[Key in string]?: JsonValue};

I would propose reverting #65 and moving back to:

export type JsonObject = {[key: string]: JsonValue};

I think it behaves more correctly, as can be seen in this playground.

Upvote & Fund

  • We're using Polar.sh so you can upvote and help fund this issue.
  • The funding will be given to active contributors.
  • Thank you in advance for helping prioritize & fund our backlog.
Fund with Polar
@sindresorhus
Copy link
Owner

I would propose reverting #65 and moving back to:

👍

@sindresorhus sindresorhus added enhancement New feature or request help wanted Extra attention is needed labels Sep 24, 2021
@voxpelli
Copy link
Collaborator Author

Since this style of JsonObject has been out for so long, I think we should maybe split it up into two types (names for illustration purposes only) to not break things unnecessarily:

  1. JsonObjectStringifiable – one that behaves like today's JsonObject. Would represent a value intended for JSON.stringify() where { foo: undefined } and plain {} are functionally equivalent.
  2. JsonObjectParsed – one that represents an actual parsed JSON value, coming from eg. JSON.parse() where undefined as a value is impossible.

Relatedly:

JSON.stringify(['foo', 1, undefined, 2])

Outputs:

["foo",1,null,2]

So I guess JsonArray should also really have a one type focused on serialization/stringification and another that properly reflects the values available in the JSON itself.

(If one wants to go crazy, then such serialization/stringification versions of the types could even include support for the toJSON method on objects)

skarab42 added a commit to skarab42/type-fest that referenced this issue Sep 15, 2022
@skarab42
Copy link
Collaborator

I would propose reverting #65 and moving back to:

export type JsonObject = {[key: string]: JsonValue};

FI: A version that supports both cases (playground) added in #465.

export type JsonObject = {[Key in string]: JsonValue} & {[Key in string]?: JsonValue | undefined};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants