Typescript 2.3 无法在 Visual Studio 中正确编译 AMD?

Typescript 2.3 not compiling AMD correctly in Visual Studio?

所以,我在使用 Typewriter 编译转换后的 C# classes 时遇到了问题。我将在下面展示的生成的打字稿无法正确编译为需要 JS 输出中的依赖项。这会导致浏览器中丢失一堆文件。

这是一个带有来自另一个文件的导入语句的打字稿示例 - 另一个文件看起来与带有导出接口的代码非常相似 Class:

如果你能帮助我理解这里发生的事情,我将不胜感激。

// -- Imports --
import { ChecklistItemState, IChecklistItemState } from './ChecklistItemState';
//

// -- Interface --
export interface IChecklistItem {

    itemId: number;
    workflowPhaseId: number;
    task: string;
    description: string;
    sortOrder: number;
    created: Date;
    modified: Date;
    state: ChecklistItemState;
}
//

// -- Knockout Class --
export class ChecklistItem {        

    itemId = ko.observable<number>();
    workflowPhaseId = ko.observable<number>();
    task = ko.observable<string>();
    description = ko.observable<string>();
    sortOrder = ko.observable<number>();
    created = ko.observable<Date>();
    modified = ko.observable<Date>();
    state = ko.observable<ChecklistItemState>();

    constructor(model: IChecklistItem) {
        this.map(model);
    }
    //

    //  -- Map Interface to Class --
    map(model: IChecklistItem) {

        this.itemId(model.itemId);
        this.workflowPhaseId(model.workflowPhaseId);
        this.task(model.task);
        this.description(model.description);
        this.sortOrder(model.sortOrder);
        this.created(model.created);
        this.modified(model.modified);
        this.state(model.state);

    }
    //



    // -- Return JSON Model --
    getModel() {
        return {

            itemId: this.itemId(),
            workflowPhaseId: this.workflowPhaseId(),
            task: this.task(),
            description: this.description(),
            sortOrder: this.sortOrder(),
            created: this.created(),
            modified: this.modified(),
            state: this.state(),

        }
    }
    //
}
//

你可以看到 ChecklistItemState 不仅在 IChecklistItem 的接口中使用,而且在 ChecklistItem 的 class 作为 'state'.

您可能会认为此代码的编译是 ./ChecklistItemState 文件的 require 语句,但这是实际编译的代码:

  define(["require", "exports"], function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    //
    // -- Knockout Class --
    var ChecklistItem = (function () {
        function ChecklistItem(model) {
            this.itemId = ko.observable();
            this.workflowPhaseId = ko.observable();
            this.task = ko.observable();
            this.description = ko.observable();
            this.sortOrder = ko.observable();
            this.created = ko.observable();
            this.modified = ko.observable();
            this.state = ko.observable();
            this.map(model);
        }
        //
        //  -- Map Interface to Class --
        ChecklistItem.prototype.map = function (model) {
            this.itemId(model.itemId);
            this.workflowPhaseId(model.workflowPhaseId);
            this.task(model.task);
            this.description(model.description);
            this.sortOrder(model.sortOrder);
            this.created(model.created);
            this.modified(model.modified);
            this.state(model.state);
        };
        //
        // -- Return JSON Model --
        ChecklistItem.prototype.getModel = function () {
            return {
                itemId: this.itemId(),
                workflowPhaseId: this.workflowPhaseId(),
                task: this.task(),
                description: this.description(),
                sortOrder: this.sortOrder(),
                created: this.created(),
                modified: this.modified(),
                state: this.state(),
            };
        };
        return ChecklistItem;
    }());
    exports.ChecklistItem = ChecklistItem;
});
//
//# sourceMappingURL=ChecklistItem.js.map  

为了证明它正确编译了其他代码,这里是另一段代码,它正确显示了已编译 JS 中的 "define" 调用。

import { SnakeViewModel } from '../../../Core/classes/SnakeViewModel';

let initModel = {
    projId: $("#projId").val(),
    wfId: $("#wfId").val()
},
viewModel;
$.post("/ProjectApi/ProjectSnakeView",
initModel,
data => {
    if (data != null) {
        console.log(data);
        var viewModel = new SnakeViewModel(data);
    }
});

然后这是该代码的编译输出:

define(["require", "exports", "../../../Core/classes/SnakeViewModel"], 
function (require, exports, SnakeViewModel_1) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var initModel = {
        projId: $("#projId").val(),
        wfId: $("#wfId").val()
    }, viewModel;
    $.post("/ProjectApi/ProjectSnakeView", initModel, function (data) {
        if (data != null) {
            console.log(data);
            var viewModel = new SnakeViewModel_1.SnakeViewModel(data);
        }
    });
});
//# sourceMappingURL=snake.js.map

编译结果对我来说很好。

当且仅当您的代码在 运行 时依赖它们时,TypeScript 编译器才会在您导入的模块的编译代码中发出依赖项 如果你的代码依赖它们只是为了类型检查,那么这是一个编译时依赖,编译器不会在编译代码中发出依赖。

在您的第一个 TypeScript 片段中,您仅在编译时依赖 ./ChecklistItemState 来执行类型检查,而不是在 运行 时,因此您没有得到对它的依赖。 (如果您添加了 new ChecklistItemStatex instanceof ChecklistItemState 之类的语句,那么您将拥有 运行 时间的依赖性,并且会在编译代码中发出依赖性。)

在您的第二个 TypeScript 片段中,您使用 new SnakeViewModel。因此您的代码需要能够在 运行 时间找到 SnakeViewModel 函数,因此您的代码需要 运行 时间依赖性 运行.