`ts-check` used with `@typedef` causes an error on `module.exports = ...`
Opened this issue · 3 comments
arcanis commented
Steps to reproduce
// @ts-check
/** @typedef {number} Foo */
module.exports = {};Behavior with typescript@5.8
No reported errors:
Behavior with tsgo
index.cjs:5:1 - error TS2309: An export assignment cannot be used in a module with other exported elements.
5 module.exports = {};
~~~~~~~~~~~~~~~~~~~
Found 1 error in index.cjs:5
This doesn't appear unless ts-check is set, even if allowJs is set to true.
jakebailey commented
#1688 would have fixed this but was closed
jakebailey commented
Here is a test case that shows a variant of this problem:
// @module: nodenext
// @target: esnext
// @outDir: ./out
// @allowJs: true
// @checkJs: true
// @noUnusedLocals: true
// @noUnusedParameters: true
// @declaration: true
// @filename: test.js
const t = require("./types");
/** @type {t.MyType} */
const obj = { a: 42, b: "hello" };
console.log(obj);
// @filename: types.js
/** @typedef {{ a: number, b: string }} MyType */
module.exports = {};Nets:
test.js(1,7): error TS6133: 't' is declared but its value is never read.
test.js(3,12): error TS2503: Cannot find namespace 't'.
types.js(3,1): error TS2309: An export assignment cannot be used in a module with other exported elements.
==== test.js (2 errors) ====
const t = require("./types");
~
!!! error TS6133: 't' is declared but its value is never read.
/** @type {t.MyType} */
~
!!! error TS2503: Cannot find namespace 't'.
const obj = { a: 42, b: "hello" };
console.log(obj);
==== types.js (1 errors) ====
/** @typedef {{ a: number, b: string }} MyType */
module.exports = {};
~~~~~~~~~~~~~~~~~~~
!!! error TS2309: An export assignment cannot be used in a module with other exported elements.
Along with:
//// [types.d.ts]
/** @typedef {{ a: number, b: string }} MyType */
export type MyType = {
a: number;
b: string;
};
declare const _default: {};
export = _default;If you remove module.exports, we still add the export modifier (another different bug), but the emit is correctish
//// [types.d.ts]
export type MyType = {
a: number;
b: string;
};
/** @typedef {{ a: number, b: string }} MyType */jakebailey commented
A workaround for type-only files like this is to not use module.exports = {}, but instead write something like module.exports.nothing = undefined which instead generates separate declarations rather than an export = node.