samchon / nestia

NestJS Helper Libraries + TypeScript OpenAPI generator
https://nestia.io/
MIT License
1.86k stars 97 forks source link

[Bug] reused type is generated duplicately in clone mode #1016

Open rojiwon123 opened 2 months ago

rojiwon123 commented 2 months ago

Bug Report

It regenerates the same type as many times as it is reused.

Summary

/** Actual behavior in Test case `clone-type-create-duplicate` */
export namespace Exception {
  /** Expected behavior */
  export type Unauthorized = {
    code: "UNAUTHORIZED";
    message: string;
  };

  export namespace Unauthorized {
   /** Unexpected behavior */
    export type o1 = {
      code: "UNAUTHORIZED";
      message: string;
    };
  }
}

This bug occurs in both Swagger build mode and SDK build mode in clone mode. It happens when you define a TypeScript type A to use as a DTO, and then create another type B that includes type A and use it as a DTO. The type A included in type B is not recognized as the same as the original type A, resulting in a new schema being generated with suffixes like .o1, .o2, and so on.

This issue is more likely to occur as the reuse of types increases. Particularly, when using union types or similar constructs, there is a high chance that types will be frequently duplicated.

I have created a reproducible environment in the latest Nestia repo. I will submit this as a PR. The test code included in the test case may be insufficient, but I have confirmed that the issue occurs.

rojiwon123 commented 2 months ago

1017 this pr about the issue.

samchon commented 2 months ago

This problem is caused by TypeScript compiler, and the TypeScript compiler is actually building duplicated types.

To solve this problem, I have to change typia's logic, and may need lots of time.

Until that, just ensure it or hope to avoiding the clone mode.

rojiwon123 commented 17 hours ago

@samchon Currently, typia's MetadataCollection.getName adds a .o{duplicates.size} suffix when type names are duplicated, which appears rather unnatural. Here's a proposed improvement:

By default, treat duplicate DTO names as the same DTO If different DTOs are needed, explicitly specify a unique name using a comment tag

This approach prevents unpredictable automatic naming while allowing developers to have explicit control over DTO names.

// in a.ts
interface DTO {
 a: string;
}
// b.ts
/** @name {CustomDTOName} */
interface DTO {
 b: string;
}