egoist / tsup

The simplest and fastest way to bundle your TypeScript libraries.
https://tsup.egoist.dev
MIT License
8.49k stars 209 forks source link

Inconsistency in generated .d.ts files #997

Open bastianccm opened 9 months ago

bastianccm commented 9 months ago

Hi!

Thanks for this nice project! We are observing an inconsistency in the generated files, which I'm not sure where they originate from. Every other run, the order of (quite deeply) nested union type definitions is switched:

diff --git a/private/integration/v1/application.d.ts b/private/integration/v1/application.d.ts
index 6d270c4..9d6cc78 100644
--- a/private/integration/v1/application.d.ts
+++ b/private/integration/v1/application.d.ts
@@ -770,7 +770,7 @@ declare const GetApplicationTemplateResponse: {
                         value?: (string[] & string[] & { [K_2 in Exclude<keyof I["template"]["fields"][number]["value"]["textList"]["value"], keyof string[]>]: never; }) | undefined;
                     } & { [K_3 in Exclude<keyof I["template"]["fields"][number]["value"]["textList"], "value">]: never; }) | undefined;
                     $case: "textList";
-                } & { [K_4 in Exclude<keyof I["template"]["fields"][number]["value"], "textList" | "$case">]: never; }) | ({
+                } & { [K_4 in Exclude<keyof I["template"]["fields"][number]["value"], "$case" | "textList">]: never; }) | ({

I've spent quite a while trying to pin this down, I noticed that rollup's dts plugin gets files fed in a random order, but even sorting them before processing does not seem to help. Rerunning this might fix it again, it seems to be completely random. So far I have not been able to create a consistent testcase outside our internal code base, but there it does happen all the time, just not in a predictable manner.

I suspect these to be the root cause:

type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;

export type DeepPartial<T> = T extends Builtin ? T
  : T extends Long ? string | number | Long : T extends Array<infer U> ? Array<DeepPartial<U>>
  : T extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>>
  : T extends { $case: string } ? { [K in keyof Omit<T, "$case">]?: DeepPartial<T[K]> } & { $case: T["$case"] }
  : T extends {} ? { [K in keyof T]?: DeepPartial<T[K]> }
  : Partial<T>;

type KeysOfUnion<T> = T extends T ? keyof T : never;
export type Exact<P, I extends P> = P extends Builtin ? P
  : P & { [K in keyof P]: Exact<P[K], I[K]> } & { [K in Exclude<keyof I, KeysOfUnion<P>>]: never };

(created by https://github.com/stephenh/ts-proto/blob/75ba9073744e0c086540a8e3ae1edad629bdf85a/src/main.ts#L573)

I'm running tsup on a list of files (~25 files), which are essentially TypeScript files generated from protobuf definitions by using ts_proto. The generated ts files do not exhibit this behaviour. This does not happen when I run tsup on each single file, unfortunately that is too slow to be used.

While I know this issue might not be in tsup, do you guys have any idea or did you observe this in the past?

Thank you, Bastian

Upvote & Fund

Fund with Polar