Typescript: Do not emit files with no statments

Created on 14 Sep 2016  路  7Comments  路  Source: microsoft/TypeScript

TypeScript Version: 2.0.2

Code

//tsconfig.json
{
    "compilerOptions": {
        "module": "amd",
        "target": "es5",
        "noImplicitAny": false,
        "sourceMap": false,
        "outFile": "out.js"
    }
}
//in person.ts
export interface Person {
    name:string,
    age:number
}
//in student.ts
import {Person} from './person'
export class Student implements Person {
    name:string;
    age:number;
    constructor(name:string, age:number) {
        this.name = name;
        this.age = age;
    }
}

Expected behavior:

define("student", ["require", "exports"], function (require, exports) {
    "use strict";
    var Student = (function () {
        function Student(name, age) {
            this.name = name;
            this.age = age;
        }
        return Student;
    }());
    exports.Student = Student;
});

Actual behavior:

define("person", ["require", "exports"], function (require, exports) {
    "use strict";
});
define("student", ["require", "exports"], function (require, exports) {
    "use strict";
    var Student = (function () {
        function Student(name, age) {
            this.name = name;
            this.age = age;
        }
        return Student;
    }());
    exports.Student = Student;
});

note: adding "noImplicitUseStrict": true provides the same result, but without usestrict statement

Working as Intended

Most helpful comment

Sure, I know that; but can't there be a emitEmpty: boolean in the compileOptions?
I'd pick that up if TypeScript guys would accept community pr for it.

All 7 comments

Well.. there is a file called person.ts that happens to be a module. so a corresponding module is created for it. if person is just a set of declarations, change it is name to person.d.ts.

Sure, that might work, but if i use declaration: true, it causes some unintended behaviour, as the d.ts file is never built, it's not available in the bunded declaration file.
This should be the also be the case if not using outFile, since it won't emit a d.ts from a d.ts. If a outDir is used, there will be no relative path from Person to Student.

It seems quite weird to me that tsc would emit empty files if no code is generated from it.

The problem is what happens when you go from a 1-statement file to a 0-statement file during separate compilations -- without emitting the blank file, you might still be loading and executing that 1 statement.

The empty module still has side effects by its mere existence that you may want to occur. Renaming to .d.ts and piping it through your build manually is the intended workaround if you want a types-only module to not be manifest despite being imported.

@RyanCavanaugh using .d.ts works locally, but the .d.ts files don't get compiled/copied out to the dist during build - which I'd need for the library. If I keep everything as .ts files, then the type/interface only files compile out to empty ts files + definition.

but the .d.ts files don't get compiled/copied out to the dist during build

$ npm install copy -g
$ copy ./src/**/*.d.ts ./dist

From the TypeScript Non-Goals:

  1. Provide an end-to-end build pipeline. Instead, make the system extensible so that external tools can use the compiler for more complex build workflows.

Sure, I know that; but can't there be a emitEmpty: boolean in the compileOptions?
I'd pick that up if TypeScript guys would accept community pr for it.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jbondc picture jbondc  路  3Comments

Roam-Cooper picture Roam-Cooper  路  3Comments

remojansen picture remojansen  路  3Comments

blendsdk picture blendsdk  路  3Comments

wmaurer picture wmaurer  路  3Comments