-
Notifications
You must be signed in to change notification settings - Fork 104
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
Feature: Add support for types from serde_json
#276
Conversation
ts-rs/src/serde_json.rs
Outdated
impl TS for serde_json::Value { | ||
type WithoutGenerics = Self; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The impl
is pretty much exactly like the one generated by
#[derive(TS)]
#[ts(untagged, export_to = "serde_json/")]
enum JsonValue {
String(String),
Number(i32),
Array(Vec<TsJsonValue>),
Object(HashMap<String, JsonValue>),
}
with the exception that it uses { [key: string]: JsonValue }
instead of Record<string, JsonValue>
.
I just realized that what would work is #[derive(TS)]
#[ts(untagged, export_to = "serde_json/")]
enum TsJsonValue {
String(String),
Number(i32),
Array(Vec<TsJsonValue>),
Object(#[ts(type = "{ [key: string]: TsJsonValue }")] ()),
} since the We can't do that in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# Conflicts: # CHANGELOG.md
Nevermind - |
Awesome! Can this PR be merged or is there anything else you'd still like to do? |
ts-rs/src/serde_json.rs
Outdated
#[derive(TS)] | ||
#[ts( | ||
crate = "crate", | ||
rename = "Value", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Last thing I'm unsure about here: Is Value
to vague? We currently don't/can't deal with name collisions, so maybe JsonValue
might be a better name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JsonValue
would be a better name, but given the use of #[ts(export_to = "serde_json/")]
I think a name collision is really unlikely
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, lemme quickly rename it. The name collision i'm more worried about is
import type { Value } from "../serde_json/Value";
import type { Value } from "../somewhere/else/Value";
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I see. I thought you were worried about the file getting overwritten
I guess this demonstrates that libraries can really just slap |
That will be awesome to see! |
Goal
This PR adds support for types from
serde_json
:serde_json::Value
,serde_json::Number
andserde_json::Map
.Most common (and most tricky) of them is
serde_json::Value
.Right now, the easiest way to get a struct containing a
Value
to implementTS
is to slap a#[ts(type = "any")]
on the fields.However, that's not great, since a JSON object is actually not
any
.If a user wanted to get a more precise type for it, they might have tried this:
Interestingly, tsc doesn't want to compile
TsJsonValue.ts
. This is one of the (rare) cases whereRecord<string, TsJsonValue>
, which is what we generate, doesn't work, but{ [key: string]: TsJsonValue }
would.Changes
In essence, all this PR does is the code above, except that
TS
had to be implemented manually forserde_json::Value
.Unlike all previous
..-impl
features, this one actually exposes an exportable type,JsonValue
.Before, all impls were simply and just generated e.g
number
. The one forserde_json::Value
, however, is recursive, and therefore needs an actual name.If a user exports a struct containing
serde_json::Value
,JsonValue.ts
will get exported to./serde_json/
.Alternatives
We could, instead of merging this now, first explore if generating
{ [key: K]: V }
for maps makes sense.Then, this PR would not require the manual TS implementation (If we made
#[derive(TS)]
work insidets_rs
, which it currently does not).(#134)
Checklist