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

DeepReadonly: Type instantiation is excessively deep and possibly infinite #276

Closed
budiirawanrapid opened this issue Dec 16, 2021 · 4 comments

Comments

@budiirawanrapid
Copy link

Setup

ts-essentials 9.0.0
typescript 4.5.4

Problem

I have this TS definition

export type JSONObject = { readonly [key in string]?: JSONValue };
export type JSONArray = JSONValue[];
export type JSONValue =
  | string
  | number
  | boolean
  | null
  | JSONArray
  | JSONObject;

Then I tried to make the typing immutable

export type MyObject = DeepReadonly<JSONObject>;

const test: MyObject = {
  id: 'a88bd472-a0c7-4e98-86d6-467d8ff1932f',
  data: {
    field1: 2,
    field2: 3,
  },
};

But I got error in Typescript

Type instantiation is excessively deep and possibly infinite

I'm sure this is because of JSONObject that could have JSONObject as the value, so it'll become infinite. Is there a better way for this scenario?

Here is the link to replicate the issue https://stackblitz.com/edit/typescript-6dunp8?file=index.ts

@Beraliv
Copy link
Collaborator

Beraliv commented Dec 19, 2021

Hey Budi @budiirawanrapid!

Thank you for the report!

I also could reproduce it here – https://tsplay.dev/WvYnrm

Looks like recursive calls are not properly handled with this declaration of types
It tries to go further and further until gets to the recursive limit

I will try to come up with a workaround or a solution and will let you know

@Beraliv
Copy link
Collaborator

Beraliv commented Dec 19, 2021

I found interesting answer on Stackoverflow about unbinding keys from original type, making it non-homomorphic – https://stackoverflow.com/a/67040809/3745332

e.g. https://tsplay.dev/W4yZKw

It helps but we lose the info about keys: they aren't optional, readonly or required anymore

Looking for other ideas

@Beraliv
Copy link
Collaborator

Beraliv commented Dec 19, 2021

That I can suggest at the moment: you can add readonly for the definition of JSONArray and then the whole object will be readonly (as every key in JSONObject is already readonly)

From our side it's quite difficult to identify infinite objects

That's why we don't support it at the moment

I will mention it in our README, but thank you anyway for your finding! 🚀

@budiirawanrapid
Copy link
Author

Hi @Beraliv, thank you so much for your response. 😄

From our side it's quite difficult to identify infinite objects

Yes, I noticed the difficulty. For JSONObject, there's no base scenario that could stop the recursion.

That I can suggest at the moment: you can add readonly for the definition of JSONArray and then the whole object will be readonly (as every key in JSONObject is already readonly)

👍 definitely will apply the readonly for JSONArray

Feel free to close this PR if no longer valid. Thank you.

@Beraliv Beraliv closed this as completed Jan 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants