Skip to content

Behavior difference: Block comments on @typedef structural types are not preserved, if they are imported and reconstructed as inline types in another file #63839

Description

A follow-up on microsoft/typescript-go#4235.


Steps to reproduce

  1. Start a plain new project
    • "@typescript/native-preview": "7.0.0-dev.20260617.2",
    • "typescript": "6.0.3"
  2. Run npx tsgo --init to get the default tsconfig. Turn on these flags as well.
    • "allowJs": true,
    • "checkJs": true,
    • "stableTypeOrdering": true,
  3. Add the below files. Run npx tsc & npx tsgo to see the difference.
/** ========> src/lib.js <======== */
/**
 * @typedef {Object} Foo
 * @property {boolean} bool Whether `.bool` is true or not
 */
export class C {
    /** @returns {Foo} */
    getFoo() { return { bool: false }; }

    /**
     * @typedef {Object} Bar
     * @property {boolean} bool Whether `.bool` is true or not
     */
    /** @returns {Bar} */
    getBar() { return { bool: false }; }
}

/** ========> src/mainJs.js <======== */
import { C } from './lib.js';

export class MainJs {
    constructor() {
        this.c = new C();
    };

    getFoo() { return { ...this.c.getFoo() }; }
    getBar() { return { ...this.c.getBar() }; }
}

/** ========> src/mainTs.ts <======== */
import { C } from './lib.js';

export class MainTs {
    constructor(public c: C) {};

    getFoo() { return { ...this.c.getFoo() }; }
    getBar() { return { ...this.c.getBar() }; }
}

Behavior with typescript@6.0

/** ========> dist/mainJs.d.ts <======== */
export class MainJs {
    c: C;
    getFoo(): {
        /**
         * Whether `.bool` is true or not
         */
        bool: boolean;
    };
    getBar(): {
        /**
         * Whether `.bool` is true or not
         */
        bool: boolean;
    };
}
import { C } from './lib.js';

/** ========> dist/mainTs.d.ts <======== */
import { C } from './lib.js';
export declare class MainTs {
    c: C;
    constructor(c: C);
    getFoo(): {
        /**
         * Whether `.bool` is true or not
         */
        bool: boolean;
    };
    getBar(): {
        /**
         * Whether `.bool` is true or not
         */
        bool: boolean;
    };
}

Behavior with tsgo

/** ========> dist/mainJs.d.ts <======== */
import { C } from './lib.js';
export declare class MainJs {
    c: C;
    constructor();
    getFoo(): {
        bool: boolean;
    };
    getBar(): {
        bool: boolean;
    };
}

/** ========> dist/mainTs.d.ts <======== */
import { C } from './lib.js';
export declare class MainTs {
    c: C;
    constructor(c: C);
    getFoo(): {
        bool: boolean;
    };
    getBar(): {
        bool: boolean;
    };
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Possible ImprovementThe current behavior isn't wrong, but it's possible to see that it might be better in some cases

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions