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

Be able to use @jsonMapMember(K,V) where V is an array. #127

Open
Jakartoine opened this issue May 22, 2020 · 6 comments
Open

Be able to use @jsonMapMember(K,V) where V is an array. #127

Jakartoine opened this issue May 22, 2020 · 6 comments

Comments

@Jakartoine
Copy link

Hey!

I have a JSON structure which is quite similar to this:
image

Naturally, I've created a model where the property displayFields
is decorated like that (where K is an enum type and V an array of a class (marked as jsonObject too)):

image

However, I have an issue while trying to parse my JSON.

Do you know a workaround or any solution to fix my issue?
Do you know if it is possible to use @jsonMapMember for that case?

Thank you in advance!

@Jakartoine
Copy link
Author

🎉 I think I found a workaround which seems to do the job! 🎉

I've created my own serializer/deserializer:
image

Pretty weird as a solution and I think this should be integrated/handled somewhere into
the library (not sure if it is a bug or a kind of "work as designed").

Here is the printed parsed property of the object in console:
image

If it can help further users, I would be happy 👍

@Neos3452
Copy link
Collaborator

Hi @Jakartoine! Thanks for opening an issue. Unfortunately you have encountered two different problems. One is sort of by design and the other is typescript limitation.

The first one is the accepted structure of maps in TypedJSON. It actually is not a dictionary but an array of {key: KeyType, value: ValueType} objects. I admit that this may not be the most friendly, but on the other hand allows to handle objects as key types.

The Typescript limitation is caused by how the types are emitted by typescript. As the generic types are erased, we don't really have a way of knowing the type that is hold by an array. We work around this for a number of types by providing custom decorators for them.

If you think this could be improved somehow just let me know.

@Jakartoine
Copy link
Author

Hey @Neos3452, Thanks for your quick answer. I couldn't expect a quicker one!

I know what you mean and I can understand the idea of "custom decorators". In fact, that sounds perfect to handle my case.

What about a new decorator named 'jsonMapArrayMember'?

It will be the exact same as 'jsonMapMember' with an exception about the inner work where the Value Constructor is the generic type of the Value Array:
image

The thing to know now is, is it possible to do something like that? Has any other developer ever needed such an operator?
Because for my personal case, the workaround I've posted above is quite fine.

Otherwise, thank you for this library. I encourage developers to use it in my company. This allows us to get more control on our models and even more so those who have deep relationships inside themselves.

TypedJSON is a timesaving and will avoid a huge boilerplate code. I've already adopted it in one of our apps used by thousands of users. My only regret is that it's not as popular as it should be. And I believe this should be part of Typescript directly.

@Neos3452
Copy link
Collaborator

Neos3452 commented May 30, 2020

Thanks for that, it means a lot :)

About your proposed solution I see one potential issue. We would need to define more decorators to support more combinations. However, for some time now, I was thinking about a different approach that could solve this issue, and others (like having an any type to skip the expected type check). The solution would be to use a special structure to define the types in the decorator. I was thinking about something like this:

    @jsonMapMember(String, ArrayT(MyClass))
    property: Map<string, MyClass[]>;

I actually prepared a POC, and you could take a look at the test that checks your particular situation here: https://github.com/Neos3452/TypedJSON/blob/type-descriptor/spec/map.spec.ts#L99

Hopefully, if typescript gets around and delivers a better reflection system this could be replaced with that.

What do you think?

@Jakartoine
Copy link
Author

@Neos3452 Thank you for your investigation!

I believe what you've done should work for my case but also for the other ones.

Any idea about a further integration? 💯

@PaulChernoch-Shell
Copy link

The answer to this issue was helpful. I did not see in the documentation any examples of the expected text syntax of the input JSON for when deserializing a Map. You should add to the docs an explanation of the key/value array syntax that you require, with an example.

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

3 participants