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

Jsonify makes Record<string, any> disappear #667

Open
kentcdodds opened this issue Aug 24, 2023 · 7 comments
Open

Jsonify makes Record<string, any> disappear #667

kentcdodds opened this issue Aug 24, 2023 · 7 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@kentcdodds
Copy link

kentcdodds commented Aug 24, 2023

Here's a TS Playground:

import type { Jsonify } from "type-fest";

type Data = Jsonify<{
  payload: Record<string, any>;
}>;

declare const d: Data;
console.log(d.payload) // <-- Property 'payload' does not exist on type 'JsonifyObject<{}>'.

This feels like a bug to me. It's causing an issue for me in the upcoming version of Remix: remix-run/remix#7246

My current workaround is to change the type to unknown instead of any (edmundhung/conform#272 which will hopefully be merged soon). I think is the proper thing to do, but sometimes that's hard because you may not control the type. I think it's more correct to keep the record around on the type.

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
@kentcdodds
Copy link
Author

Behavior confirmed via #668 PR workflow run: https://github.com/sindresorhus/type-fest/actions/runs/5959009025/job/16164096431?pr=668#step:5:11

  ✖  331:43  Argument of type JsonifyObject<{}> is not assignable to parameter of type { payload: Record<string, any>; }.
  Property payload is missing in type JsonifyObject<{}> but required in type { payload: Record<string, any>; }.  

@sindresorhus
Copy link
Owner

I agree. Record<string, any> is already passed through when it's top-level, and it makes sense to also do it when it's a property.

@sindresorhus sindresorhus added enhancement New feature or request help wanted Extra attention is needed labels Aug 24, 2023
@MichaelDeBoey
Copy link
Contributor

MichaelDeBoey commented Aug 24, 2023

Same issue happens when having Record<string, string> or Record<string, Date>

CC/ @sachinraja as he created the original JsonifyObject generic in #519, so maybe he has an idea of where the problem would be?

@sachinraja
Copy link
Contributor

I’ll take a look when I can but that type actually comes from Remix's initial jsonify implementation

@MichaelDeBoey
Copy link
Contributor

@sachinraja Is there anything I can help you with to get this one fixed?

@pcattori
Copy link
Contributor

pcattori commented Oct 3, 2023

Tried reproducing this. At first, looks like the issue is resolved since there aren't red squigglies, but then I noticed that payload gets inferred as a number 🤷

https://tsplay.dev/mZJO1m

Screenshot 2023-10-03 at 12 17 33 PM

I'm looking into this now

@pcattori
Copy link
Contributor

pcattori commented Oct 3, 2023

Ok tracked this down to this line:

T extends TypedArray ? Record<string, number> :
// ...

That extends TypedArray check triggers for Record<string, any>. Similar to how IsAny is checked at the beginning of Jsonify, we need to check for Record<string, any> before any other extends Record<string, _> checks (which TypedArray implicitly is).

Here's a minimal repro with suggested fix: https://tsplay.dev/N7VJqw

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
5 participants