Skip to content

Typescript: Option<> does not include null in generated types #244

Open

Description

@maiia-kuzmishyna

Description

We are using typeshare to auto-translate Rust types into Typescript ones and facing issues with Option<> type.
Assume we have the following type:

#[typeshare]
struct MyStruct {
    my_name: Option<String>,
    my_age: u32,
}

The issue is that unless we are using #[serde(skip_serializing_if = "Option::is_none")] attribute, then if my_name has value None it gets serialized as null in JSON:

{
  "my_name": null,
  "my_age": 21
}

However, the generated Typescript definition does not reflect that my_name can hold a null value:

/*
 Generated by typeshare 1.13.2
*/

export interface MyStruct {
  my_name?: string;
  my_age: number;
}

This leads to potential unchecked nulls in our typescript part of the project.

Proposed solution

The best solution would be to adapt how Option<> types are treated based on the presence or absence of serde attribute.
If this is not possible, then null could simply be added to type definition of optional properties, enforcing safer typechecking.
However, that might be a breaking change to projects already relying on serde attribute so perhaps there should be a command line option to opt-in to this behavior.

Related issues

There is a similar issue about unit type: #43 which has been attempted to be fixed by #82 however reverted due to #96 and now is hanging in a draft pr #98.

Version

typeshare-cli version 1.13.2
typeshare crate version 1.0.4

Activity

  1. maiia-kuzmishyna commented on Jun 19, 2025

    @maiia-kuzmishyna
    Author

    Additionally, typeshare incorrectly maps nested Option<T> , for example in arrays, e.g.

    pub array: Vec<Option<String>>
    

    gets mapped to

    array: string[]
    

    This completely hides the information that an individual element of array can be null.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions