-
-
Notifications
You must be signed in to change notification settings - Fork 546
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
Fix/Refine Type Inference for Objects with toJSON() Extending Primitives #690
Fix/Refine Type Inference for Objects with toJSON() Extending Primitives #690
Conversation
Ensure objects implementing `toJSON()`, but also extending primitive types, have their type inferred by `toJSON()` and not by the extended type. This refinement helps prevent incorrect type inference for specialized objects with enhanced serialization. Changes: - Updated type conditions in `source/jsonify.d.ts` by prioritizing `{toJSON(): infer J}` case before primitives. - Added corresponding test cases in `test-d/jsonify.ts`. Example: This fix resolves issues like the incorrect inference of `Jsonify<Temporal.PlainDate>`, where `Temporal` is sourced from `@js-temporal/polyfill` and where `PlainDate` is extending `Boolean`. ```typescript import { Temporal } from '@js-temporal/polyfill'; // Incorrectly inferred as Boolean, but string is expected Jsonify<Temporal.PlainDate> ```
Hi @sindresorhus, I hope my PR has all the info you need. As used as an example in the commit msg, I ran into the issue when using I think objects that implement Thanks for checking it out! |
@darcyparker – may I bring this PR to your attention as you have been the contributor of #257 which allowed |
@nrako - The meaning of In my view: https://github.com/sindresorhus/type-fest/blob/main/source/jsonifiable.d.ts#L3 is not the right definition. (@itsjohncs FYI). It might be okay... but it's worth re-consideration. I think 2 cases are being clubbed together and there is value in keeping them separate. There is certainly a use case for a type that is See these cases: I am also not sure about adding the The reason
Neither is assignable to
Now you can pass I think what you're getting at is that you want something for cases like:
where
(I haven't tested TLDR; I think people are reading too much into the intent of This is open for discussion.. and probably should be spawned into an issue to talk about. |
@darcyparker – thanks for taking the time to look into this.
Did you meant to link
Actually my usage is more akin to the example of import type {Jsonify} from 'type-fest';
import { Temporal } from '@js-temporal/polyfill'
const time = {
dateValue: Temporal.Now.plainDateTimeISO()
};
// `Jsonify<typeof time>` SHOULD BE the equivalent of `{dateValue: string}` RIGHT NOW we get `{dateValue: Boolean}`
const timeJson = JSON.parse(JSON.stringify(time)) as Jsonify<typeof time>; To be more specific, I've encountered this issue while trying Remix v2 which is now using I've seen that someone mentioned using |
No - I meant Sure I do understand there is a need for a utility to do a transformation that transforms a value like So I think there could be a new type called Another viewpoint is that we should club the concepts of what I think of as |
Okay, I think my understanding got muddled with all the " I understand that
Nor are you certain about the Map and Set cases. And that type-fest/source/jsonifiable.d.ts Line 3 in 113400b
Or that you believe the Thus, you're advocating for a new new type Jsonable = {
toJSON: <T extends JsonValue>() => T;
}
And I caught that you're suggesting spawning a new discussion for this, which I'd certainly agree with, but I don't feel I have the right insights to start this effectively so I can only encourage you to consider doing it. Now, in practical terms for the scope of my changes in this PR, which are meant to fix the issue I encountered; I unfortunately still fail to understand how I'm only just catching up with some concepts of type-fest and I'm not trying to question pre-existing implementations, nor introduce new concepts, or significantly change existing ones; I'm just trying to find the simplest and correct path to fix the issue I raised. @darcyparker – I've asked for your insights because you are the author of #257 which first introduced the handling of I would like to emphasize that the essence of this PR only moves the I believe the issue, which this PR aims to fix, would also occur on 4184e18. With my humble understanding, no other changes – questionable or not – made since then have a direct impact on the problem or the solution AFAICT. |
Sorry - yes this is getting confusing. And I am confusing myself too. I forgot about #257, and in retrospect I am not sure I like it. I hear your point about moving the extends {toJSON(): infer J} to after. That's okay with me given |
Okay thanks. It looks we agree on this fix then. @sindresorhus - how can we move on with this? |
Ensure objects implementing
toJSON()
, but also extending primitive types, have their type inferred bytoJSON()
and not by the extended type. This refinement helps prevent incorrect type inference for specialized objects with enhanced serialization.Changes:
- Updated type conditions in
source/jsonify.d.ts
by prioritizing{toJSON(): infer J}
case before primitives.- Added corresponding test cases in
test-d/jsonify.ts
.Example:
This fix resolves issues like the incorrect inference of
Jsonify<Temporal.PlainDate>
, whereTemporal
is sourced from@js-temporal/polyfill
and wherePlainDate
is extendingBoolean
.