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

问题描述:

因此,我遇到了使用打字机编译转换后的C#类的问题。我将在下面显示的打字稿无法正确编译为需要JS输出中的依赖关系。这会导致浏览器中一堆丢失的文件。Typescript 2.3无法在Visual Studio中正确编译AMD?

这里是从另一个文件中的import语句的打字稿的例子 - 其他文件看起来非常相似,这个代码与导出接口和类:

如果你能帮助我理解这里发生了什么它将不胜感激。

// -- 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(), 

     } 
    } 
    // 
} 
// 

你可以看到正在使用不仅在IChecklistItem的接口也是类ChecklistItem作为“国家” ChecklistItemState。

你可以想象这个代码的编译是为./ChecklistItemState文件要求语句,但这里是实际的编译代码:

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 ChecklistItemState一个x instanceof ChecklistItemState声明,那么你就会有一个运行时depenency和将得到的编译代码发出的依赖关系。)

在你的第二打字稿片段,您可以使用new SnakeViewModel。因此,您的代码需要能够在运行时找到SnakeViewModel函数,因此运行代码需要运行时依赖性。

+0

好的,那让我对此有所了解。所以现在我需要弄清楚为什么var viewModel = new SnakeViewModel(data);'返回undefined .. SnakeViewModel类似ChecklistItem类的结构更加复杂。关于下一步的任何想法? – Aquaritek

+0

如果'viewModel'保持未定义状态,这与您在编写问题时关注的问题不同。你正在处理异步代码。你确定你正在查看'viewModel'吗?你有没有尝试在'var viewModel = new SnakeViewModel(data);'后面查看'viewModel'具有什么值,然后立即**放置'console.log' **?在'new'调用之后,'console.log'必须**立即**,而不是例如在你的模块结尾。 (我也看到你定义了'viewModel'两次:在模块的外部范围和回调中。) – Louis

+0

原来这是标题与骆驼的问题 - 呃...现在我意识到我的KO可观察值是只有一个深度...在这里,我们继续穿越并实例化来自SnakeViewModel :)的每个较低级别的对象。谢谢你让我在脑海中摆脱杂草。 – Aquaritek