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

Incorrect tagged unions when using Jackson and nested subtypes #1005

Open
JoaoBrlt opened this issue Sep 3, 2023 · 0 comments
Open

Incorrect tagged unions when using Jackson and nested subtypes #1005

JoaoBrlt opened this issue Sep 3, 2023 · 0 comments

Comments

@JoaoBrlt
Copy link

JoaoBrlt commented Sep 3, 2023

Hi there,

First of all, I'd like to thank you for the amazing work behind this tool!
It's a fantastic tool that saves us a lot of time, while ensuring that types are respected on the client side.

Context

I'm currently using TypeScript Generator to generate TypeScript declarations for a large hierarchy of Java classes.
These classes have several levels of depth and are serialized/deserialized using Jackson.
I use the @JsonTypeInfo annotation on the root class and the @JsonSubTypes annotation at each depth level.
This way serialization/deserialization works and TypeScript Generator generates tagged unions which I need to properly type these classes. 👌

Actual behavior

The only issue is that classes referencing intermediate subtypes (classes referencing other subtypes) seem to generate incorrect tagged unions.
Indeed, tagged unions always seem to reference interface declarations and not the tagged unions of the subtypes (when they exist).

Expected behavior

I would expect the tagged unions to reference the tagged unions of the subtypes (when they exist).

Steps to reproduce

I created a small project to demonstrate the issue: typescript-generator-nested-subtypes.

The project is composed of the following classes:

The generated TypeScript declaration file is available here and looks like this:

export interface Animal {...}
export interface Mammal extends Animal {...}
export interface Bird extends Animal {...}
export interface Cat extends Mammal {...}
export interface Dog extends Mammal {...}
export interface Parrot extends Bird {...}
export interface Duck extends Bird {...}

export type AnimalUnion = Mammal | Bird;
export type MammalUnion = Cat | Dog;
export type BirdUnion = Parrot | Duck;

This means I cannot write something like this:

const animal: AnimalUnion = {
    type: "Cat",
    name: "Mittens",
    age: 3,
    numberOfLegs: 4,
    breed: "Tabby",
    favoriteMeal: "Tuna",
    children: [],
};

Indeed, this generates a TypeScript error:

Type '{ type: "Cat"; name: string; age: number; numberOfLegs: number; breed: string; favoriteMeal: string; children: never[]; }' is not assignable to type 'AnimalUnion'.
Object literal may only specify known properties, and 'breed' does not exist in type 'Mammal'.(2322)

For this reason, I would expected the generated tagged unions to look like this:

export type AnimalUnion = MammalUnion | BirdUnion;
export type MammalUnion = Cat | Dog;
export type BirdUnion = Parrot | Duck;

Don't hesitate to tell me if I missed something.

Cheers!

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

1 participant