Skip to content

Generated .d.ts files from JS project are invalid #41258

Closed
@Gozala

Description

@Gozala

TypeScript Version: 3.7.x-dev.201xxxxx

Search Terms:

Code

lib.js

/**
 * @template T
 * @implements {IEncoder<T>}
 */
export class Encoder {
  /**
   * @param {T} value 
   */
  encode(value) {
    return new Uint8Array(0)
  }
}


/**
 * @template T
 * @typedef {import('./interface').Encoder<T>} IEncoder
 */

interface.ts

export interface Encoder<T> {
  encode(value:T): Uint8Array
}

Expected behavior:

Generating typedefs should generate TS file that type checks, e.g. for lib.js it should produce something like:

/**
 * @template T
 * @implements {IEncoder<T>}
 */
export class EncoderImpl<T> implements IEncoder<T> {
    /**
     * @param {T} value
     */
    encode(value: T): Uint8Array;
}

import { Encoder as IEncoder } from "./interface"

Actual behavior:

Instead tsc generates lib.d.ts file which does not type check, because type parameters are omitted

/**
 * @template T
 * @implements {IEncoder<T>}
 */
export class EncoderImpl<T> implements Encoder {
    /**
     * @param {T} value
     */
    encode(value: T): Uint8Array;
}
export type IEncoder<T> = import("./interface").Encoder<T>;

Playground Link:

Can't make a playground link because it requires multiple files, but here is the repo with the above example
https://github.com/Gozala/tsc-implements-bug

Related Issues:

Unfortunately it's not just that type parameters are omitted, but also the fact that importing interface turns it into a type which then can't be used as implements target.

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