microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
101.08k stars 12.49k forks source link

"export class" does not compile with outfile=foo (module=none, es6) #37619

Open HolgerJeromin opened 4 years ago

HolgerJeromin commented 4 years ago

TypeScript Version: 3.8.3

Search Terms:

Code

{
   "$schema": "http://json.schemastore.org/tsconfig",
   "compilerOptions": {
      "module": "none",
      "target": "es6",
      "types": [],
      "outFile": "newFile.js" //   <- important
   },
   "files": [
      "main.ts"
   ]
}
// main.ts
declare module Common {
    abstract class absCom {
        constructor();
    }
}
export /* <- important */ class Com extends Common.absCom {
    constructor() {
        super();
    }
}

Expected behavior: This should compile without problems. Actual behavior: When I configure an outfile no file is generated (js and no .d.ts, .js.map). But we get no error message about this! This is the same with --verbose:

[13:11:21] Project 'foo/tsconfig.json' is out of date because output file 'foo/newFile.js' does not exist
[13:11:21] Building project 'foo/tsconfig.json'...
[13:11:23] Updating unchanged output timestamps of project 'foo/tsconfig.json'...

Test 1: Removing the outfile generates the following block in main.js:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class Com extends Common.absCom {
    constructor() {
        super();
    }
}
exports.Com = Com;

Test 2: Removing export in main.ts we get in newFile.js:

class Com extends Common.absCom {
    constructor() {
        super();
    }
}

Thats why I think merging Object.defineProperty(exports, "__esModule", { value: true }); into one outfile causes the abort.

Playground Link: Not possible, as we need outfile to trigger the bug.

Related Issues: none found

nmain commented 4 years ago

Per the docs, outFile is only legal when module is AMD or System, but the lack of error message seems like a bug.

HolgerJeromin commented 4 years ago

Wow. We are using outFile with module=none for over five years without problems.

HolgerJeromin commented 4 years ago

I always interpreted the docs as

The only module loader that can be used in conjunction with --outFile are "AMD" and "System".

and not as

Only the values "AMD" and "System" can be used in conjunction with --outFile. Even "None" is not allowed.

Waiting for feedback from product owner.

HolgerJeromin commented 4 years ago

The new website explains it: https://www.typescriptlang.org/tsconfig#outFile

Note: outFile cannot be used unless module is None, System, or AMD. This option cannot be used to bundle CommonJS or ES6 modules.

So our code is valid :-)

HolgerJeromin commented 4 years ago

This one does not compile either with NO error message:

export interface myInterface{
  value: boolean;
}
function a(){}

Works without problems when removing export.

HolgerJeromin commented 3 years ago

Even easier to reproduce:

/* Fixing self https://github.com/microsoft/TypeScript/issues/11781 */
declare var self: ServiceWorkerGlobalScope; // eslint-disable-line @typescript-eslint/no-redeclare
export { };

with


    "compilerOptions": {
        "lib": [
            "WebWorker",
            "scripthost",
            "ESNext"
        ],
        "outFile": "ServiceWorker.js"