Skip to content

Declaration emit does not remember the names it assigned to certain type parameters #58627

@weswigham

Description

@weswigham

🔎 Search Terms

declaration emit wrong name

🕗 Version & Regression Information

  • This changed in 5.5-beta

Declaration emit keeps the names of some type parameters now, but fails to assign those names to references to those type parameters later in the serialized type.

Playground Link

💻 Code

export interface TypeLambda {
  readonly In: unknown
  readonly Out2: unknown
  readonly Out1: unknown
  readonly Target: unknown
}
namespace Types {
  export type Invariant<A> = (_: A) => A
  export type Covariant<A> = (_: never) => A
  export type Contravariant<A> = (_: A) => void
}

export declare const URI: unique symbol;
export interface TypeClass<F extends TypeLambda> {
  readonly [URI]?: F
}

export interface Invariant<F extends TypeLambda> extends TypeClass<F> {
  readonly imap: {
    <A, B>(
      to: (a: A) => B,
      from: (b: B) => A
    ): <R, O, E>(self: Kind<F, R, O, E, A>) => Kind<F, R, O, E, B>
    <R, O, E, A, B>(
      self: Kind<F, R, O, E, A>,
      to: (a: A) => B,
      from: (b: B) => A
    ): Kind<F, R, O, E, B>
  }
}

export interface Covariant<F extends TypeLambda> extends Invariant<F> {
  readonly map: {
    <A, B>(f: (a: A) => B): <R, O, E>(self: Kind<F, R, O, E, A>) => Kind<F, R, O, E, B>
    <R, O, E, A, B>(self: Kind<F, R, O, E, A>, f: (a: A) => B): Kind<F, R, O, E, B>
  }
}


export type Kind<F extends TypeLambda, In, Out2, Out1, Target> = F extends {
  readonly type: unknown
} ? (F & {
    readonly In: In
    readonly Out2: Out2
    readonly Out1: Out1
    readonly Target: Target
  })["type"]
  : {
    readonly F: F
    readonly In: Types.Contravariant<In>
    readonly Out2: Types.Covariant<Out2>
    readonly Out1: Types.Covariant<Out1>
    readonly Target: Types.Invariant<Target>
  }

export interface SemiProduct<F extends TypeLambda> extends Invariant<F> {
  readonly product: <R1, O1, E1, A, R2, O2, E2, B>(
    self: Kind<F, R1, O1, E1, A>,
    that: Kind<F, R2, O2, E2, B>
  ) => Kind<F, R1 & R2, O1 | O2, E1 | E2, [A, B]>

  readonly productMany: <R, O, E, A>(
    self: Kind<F, R, O, E, A>,
    collection: Iterable<Kind<F, R, O, E, A>>
  ) => Kind<F, R, O, E, [A, ...Array<A>]>
}
export interface SemiApplicative<F extends TypeLambda> extends SemiProduct<F>, Covariant<F> {}


export const SK = <A, B>(_: A, b: B): B => b;

export declare const dual: {
  <DataLast extends (...args: Array<any>) => any, DataFirst extends (...args: Array<any>) => any>(
    arity: Parameters<DataFirst>["length"],
    body: DataFirst
  ): DataLast & DataFirst
  <DataLast extends (...args: Array<any>) => any, DataFirst extends (...args: Array<any>) => any>(
    isDataFirst: (args: IArguments) => boolean,
    body: DataFirst
  ): DataLast & DataFirst
};

export const zipWith = <F extends TypeLambda>(F: SemiApplicative<F>): {
  <R2, O2, E2, B, A, C>(
    that: Kind<F, R2, O2, E2, B>,
    f: (a: A, b: B) => C
  ): <R1, O1, E1>(self: Kind<F, R1, O1, E1, A>) => Kind<F, R1 & R2, O2 | O1, E2 | E1, C>
  <R1, O1, E1, A, R2, O2, E2, B, C>(
    self: Kind<F, R1, O1, E1, A>,
    that: Kind<F, R2, O2, E2, B>,
    f: (a: A, b: B) => C
  ): Kind<F, R1 & R2, O1 | O2, E1 | E2, C>
} =>
  dual(
    3,
    <R1, O1, E1, A, R2, O2, E2, B, C>(
      self: Kind<F, R1, O1, E1, A>,
      that: Kind<F, R2, O2, E2, B>,
      f: (a: A, b: B) => C
    ): Kind<F, R1 & R2, O1 | O2, E1 | E2, C> => F.map(F.product(self, that), ([a, b]) => f(a, b))
  )


export const zipRight = <F extends TypeLambda>(F: SemiApplicative<F>): {
  <R2, O2, E2, B>(
    that: Kind<F, R2, O2, E2, B>
  ): <R1, O1, E1, _>(self: Kind<F, R1, O1, E1, _>) => Kind<F, R1 & R2, O2 | O1, E2 | E1, B>
  <R1, O1, E1, _, R2, O2, E2, B>(
    self: Kind<F, R1, O1, E1, _>,
    that: Kind<F, R2, O2, E2, B>
  ): Kind<F, R1 & R2, O1 | O2, E1 | E2, B>
} =>
  dual(2, <R1, O1, E1, _, R2, O2, E2, B>(
    self: Kind<F, R1, O1, E1, _>,
    that: Kind<F, R2, O2, E2, B>
  ): Kind<F, R1 & R2, O1 | O2, E1 | E2, B> => zipWith(F)(self, that, SK))

🙁 Actual behavior

Declaration emit is

export declare const zipRight: <F extends TypeLambda>(F: SemiApplicative<F>) => {
    <R2, O2, E2, B>(that: Kind<F, R2, O2, E2, B>): <R1, O1, E1, _>(self: Kind<F, R1, O1, E1, _>) => Kind<F, R1 & R2, O2 | O1, E2 | E1, B>;
    <R1, O1, E1, _, R2, O2, E2, B>(self: Kind<F, R1, O1_1, E1_1, __1>, that: Kind<F, R2, O2_1, E2_1, B_1>): Kind<F, R1 & R2, O1_1 | O2_1, E1_1 | E2_1, B_1>;
};

🙂 Expected behavior

Declaration emit is

export declare const zipRight: <F extends TypeLambda>(F: SemiApplicative<F>) => {
    <R2, O2, E2, B>(that: Kind<F, R2, O2, E2, B>): <R1, O1, E1, _>(self: Kind<F, R1, O1, E1, _>) => Kind<F, R1 & R2, O2 | O1, E2 | E1, B>;
    <R1_1, O1_1, E1_1, __1, R2_1, O2_1, E2_1, B_1>(self: Kind<F, R1_1, O1_1, E1_1, __1>, that: Kind<F, R2_1, O2_1, E2_1, B_1>): Kind<F, R1_1 & R2_1, O1_1 | O2_1, E1_1 | E2_1, B_1>;
};

as in 5.4.5 or semantically equivalent. Or at least correct.

Additional information about the issue

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Domain: Declaration EmitThe issue relates to the emission of d.ts filesFix AvailableA PR has been opened for this issueRecent RegressionThis is a new regression just found in the last major/minor version of TypeScript.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions