-
Notifications
You must be signed in to change notification settings - Fork 115
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
Optional Options should have a null
type
#112
Comments
I agree that I propose we replace this with two concepts: optional ( I have a patch that does something sort of like this (main...petersn:ts-rs:optional-changes although it's mixed in with other changes), but I'm curious what the maintainers think is the right behavior here. |
@NyxCode, what do you think the behavior should be? Should we keep it as is or add an |
I started writing a reply, and while writing it realized how complex the different tradeoffs are here. Interactions with
|
Rust type | serializes to | deserializes from | possible TS types |
---|---|---|---|
Option<T> |
null |
null |
t: T | null |
#[serde(default)] Option<T> |
null |
null | undefined |
t: T | null t?: T | null |
#[serde(skip_serializing_if = "is_none")] Option<T> |
undefined |
null |
NONE |
#[serde(default)] #[serde(skip_serializing_if = "is_none")] Option<T> |
undefined |
null | undefined |
t?: T t?: T | null |
Proposal
We keep #[ts(optional)]
as it currently is, but also introduce #[ts(nullable)]
.
That attribute would be used with #[ts(optional)]
to do what is proposed here.
#[serde(default)]
The two possible TS types for this are t: T | null
or t?: T | null
.
The first one is the smaller type, so it should be the default.
Therefore, we can just ignore the attribute, since t: T | null
is what Option<T>
get's turned into anyway.
To get the 2nd one, a user can additionally use #[ts(optional, nullable)]
#[serde(skip_serializing_if = "Option::is_none")]
This should result in a warning!
There is no type we could possibly generate that would fit, as far as I can tell.
#[serde(default)]
and #[serde(skip_serializing_if = "Option::is_none")]
The two possible TS types for this are t?: T
or t?: T | null
.
The first one is the smaller type, so it should be the default.
Therefore, these two serde attributes would get translated into #[ts(optional)]
.
To get the 2nd one, a user can additionally use #[ts(nullable)]
Summary
This is a complicated topic, and I'm still not sure this is the right way.
Any opinions or thoughts on this @escritorio-gustavo ?
A smaller sensible change, without introducing Previously, just Adding that back in, as long as |
Your smallest possible set idea makes a lot of sense, because it guarantees that the resulting type can always be serialized and deserialized. I also think re adding |
Not sure if I misread this, or if there was a misunderstanding. But using the "smallest" type is not strictly neccessary. In the table, there are two possible types for e.g I think however that one motivation of @ryanw to open the issue was that
I'm sceptical about that. Maybe some users got types which they only deserialize, and never serialize.
I do agree that we probably want to add that back. Though I'd like non- |
I misunderstood, I missed the fact that even if, say,
That makes sense, let's keep it to a warning
I see. I think |
Currently this:
Will generate:
But this:
Will generate:
This means it's not possible to assign the required value to the
#[ts(optional)]
one as you end up with the error:It seems to be me that the
#[ts(optional)]
attribute shouldn't change the type at all, and simply adds the?
to the field. i.e. It should spit out:The text was updated successfully, but these errors were encountered: