Skip to content

Regression: bug in emitted declarations involving branded types since 5.1 #54655

Closed
@GabeAtWork

Description

@GabeAtWork

Bug Report

Code that used to compile fine in 5.0.0 now produces invalid declarations with type names suffixed in _1 which are not defined (see code below).

🔎 Search Terms

Branded type, suffix, emit

🕗 Version & Regression Information

  • This changed between versions 5.0.0 and 5.1.3

⏯ Playground Link

Playground link with relevant code

💻 Code

// A simple branded type definition
export type Brand<
  Base,
  Branding,
  ReservedName extends string = "__type__"
> = Base & { [K in ReservedName]: Branding } & { __witness__: Base };

// Defining a branded type
export type BoundedInteger<
  LowerBound extends number,
  UpperBound extends number
> = Brand<number, "BoundedInteger">;

// Using in in a function
export const toBoundedInteger =
  <LowerBound extends number, UpperBound extends number>(bounds: {
    lowerBound: LowerBound;
    upperBound: UpperBound;
  }) =>
  (
    n: number
  ): BoundedInteger<LowerBound, UpperBound> =>
  // Implementation doesn't matter here
    ({} as any)

🙁 Actual behavior

// v5.1.3
// in D.TS

export type Brand<Base, Branding, ReservedName extends string = "__type__"> = Base & {
    [K in ReservedName]: Branding;
} & {
    __witness__: Base;
};
export type BoundedInteger<LowerBound extends number, UpperBound extends number> = Brand<number, "BoundedInteger">;
export declare const toBoundedInteger: <LowerBound extends number, UpperBound extends number>(bounds: {
    lowerBound: LowerBound;
    upperBound: UpperBound;
// ❌ Cannot find name 'LowerBound_1'. Did you mean 'LowerBound'?
}) => (n: number) => BoundedInteger<LowerBound_1, UpperBound_1>;
// 👆 This line

🙂 Expected behavior

// v5.0.4
// in D.TS

export type Brand<Base, Branding, ReservedName extends string = "__type__"> = Base & {
    [K in ReservedName]: Branding;
} & {
    __witness__: Base;
};
export type BoundedInteger<LowerBound extends number, UpperBound extends number> = Brand<number, "BoundedInteger">;
export declare const toBoundedInteger: <LowerBound extends number, UpperBound extends number>(bounds: {
    lowerBound: LowerBound;
    upperBound: UpperBound;
}) => (n: number) => BoundedInteger<LowerBound, UpperBound>;
// 👆 This line

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptFix AvailableA PR has been opened for this issue

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions