如何在TypeScript中基于接口文件定义创build一个对象?

我已经定义了这样一个接口:

interface IModal { content: string; form: string; href: string; $form: JQuery; $message: JQuery; $modal: JQuery; $submits: JQuery; } 

我定义了一个像这样的variables:

 var modal: IModal; 

但是,当我尝试设置模态的属性时,它给了我一个消息说

 "cannot set property content of undefined" 

有人可以帮我弄这个吗? 使用界面来描述我的模态对象是否可以,如果可以,我应该如何创build它?

如果你正在其他地方创build“模态”variables,并且想告诉TypeScript它将全部完成,你可以使用:

 declare var modal: IModal; 

如果你想在TypeScript中创build一个实际上是IModal实例的variables,你需要完全定义它。

 var modal: IModal = { content: '', form: '', href: '', $form: null, $message: null, $modal: null, $submits: null }; 

或者用types断言说谎,但是你会丢失types安全性,因为在访问modal.content等(合约所说的属性)时,你现在会在意想不到的地方得到未定义的,并且可能是运行时错误。

 var modal = <IModal>{}; 

示例类

 class Modal implements IModal { content: string; form: string; href: string; $form: JQuery; $message: JQuery; $modal: JQuery; $submits: JQuery; } var modal = new Modal(); 

你可能会认为“嘿,这真的是一个界面的重复” – 你是对的。 如果Modal类是IModal接口的唯一实现,则可能需要完全删除该接口并使用…

 var modal: Modal = new Modal(); 

而不是

 var modal: IModal = new Modal(); 

如果你想要一个接口的空对象,你可以只做:

 var modal = <IModal>{}; 

使用接口代替结构化数据的类的优点是,如果你没有任何类的方法,它将在编译后的JS中显示为空方法。 例:

 class TestClass { a: number; b: string; c: boolean; } 

编译成

 var TestClass = (function () { function TestClass() { } return TestClass; })(); 

没有价值。 另一方面,接口不会显示在JS中,同时还提供了数据结构和types检查的好处。

我想你基本上有五种不同的select 。 根据你想达到的目标,select它们可能很容易。

在大多数情况下, 使用类并实例化它的最好方法是,因为您正在使用TypeScript来应用types检查。

 interface IModal { content: string; form: string; //... //Extra foo: (bar: string): void; } class Modal implements IModal { content: string; form: string; foo(param: string): void { } } 

即使其他方法提供了从界面创build对象的更简单的方法,如果您将对象用于不同的事情,并且不会导致界面过度分离,您应该考虑拆分您的界面。

 interface IBehaviour { //Extra foo(param: string): void; } interface IModal extends IBehaviour{ content: string; form: string; //... } 

另一方面,例如,在unit testing代码的过程中(如果您不经常分离关注点),为了提高生产力,您可能会接受这些缺点。 您可以使用其他方法来创build主要为大型第三方* .d.ts接口的模拟。 总是为每个巨大的接口实现完整的匿名对象可能是一件痛苦的事情。

在这个path上,你的第一个select是创build一个空的对象

  var modal = <IModal>{}; 

其次要充分实现界面的必要部分 。 无论您是在调用第三方JavaScript库,这都会很有用,但我认为您应该像以前一样创build一个类:

 var modal: IModal = { content: '', form: '', //... foo: (param: string): void => { } }; 

第三,你可以只创build你的接口一部分,并创build一个匿名的对象 ,但这样你有责任履行合同

 var modal: IModal = <any>{ foo: (param: string): void => { } }; 

总结我的答案,即使接口是可选的,因为它们没有被转换成JavaScript代码,如果明智和一致地使用,TypeScript将提供一个新的抽象级别。 我认为,仅仅因为你可以在你自己的代码的大部分情况下解雇他们,你不应该这样做。

如果你使用的是React,parsing器会扼杀传统的强制转换语法,所以在.tsx文件中引入了一个替代scheme

 let a = {} as MyInterface; 

https://www.typescriptlang.org/docs/handbook/jsx.html

使用你的界面,你可以做

 class Modal() { constructor(public iModal: IModal) { //You now have access to all your interface variables using this.iModal object, //you don't need to define the properties at all, constructor does it for you. } }