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

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

我这样定义一个变量:

var modal: IModal;

然而,当我尝试设置modal属性时,它会给我一个消息说

"cannot set property content of undefined"

是否可以使用接口来描述我的模态对象,如果是这样,我应该如何创建它?


当前回答

这里是我经常使用的另一个解决方案。但是我不确定这是否是好的做法,如果不是,请在下面评论。

/// Interface
export default interface BookInterface {
  title: string,
  author: string,
  id: any
}

/// Creating Class
export class BookClass implements BookInterface {
  title: string;
  author: string;
  id: any;

  constructor(title: string, author: string, id: any) {
    this.title = title;
    this.author = author;
    this.id = id;
  }
}

/// How to use it
let book: BookInterface = new BookClass(title, author, id);

谢谢:)

其他回答

你可以这样做

var modal = {} as IModal 

如果你在其他地方创建了“modal”变量,并想告诉TypeScript它将全部完成,你可以使用:

declare const modal: IModal;

如果你想创建一个实际上是TypeScript中IModal实例的变量,你需要完整地定义它。

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

或者撒谎,使用类型断言,但是你会失去类型安全,因为你现在会在意想不到的地方得到未定义,并且可能在访问modal时出现运行时错误。内容等(合同规定的属性)。

const modal = {} as IModal;

示例类

class Modal implements IModal {
    content: string;
    form: string;
    href: string;
    $form: JQuery;
    $message: JQuery;
    $modal: JQuery;
    $submits: JQuery;
}

const modal = new Modal();

你可能会想“嘿,这真的是一个重复的界面”-你是正确的。如果Modal类是IModal接口的唯一实现,你可能想要删除整个接口并使用…

const modal: Modal = new Modal();

而不是

const modal: IModal = new Modal();

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

var modal = <IModal>{};

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

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

编译成

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

没有任何价值。另一方面,接口根本不会出现在JS中,同时仍然提供数据结构和类型检查的好处。

我认为你基本上有五种不同的选择。根据你想要达到的目标,从中选择可能很容易。

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

interface IModal {
    content: string;
    form: string;
    //...

    //Extra
    foo: (bar: string): void;
}

class Modal implements IModal {
    content: string;
    form: string;

    foo(param: string): void {
    }
}

即使其他方法提供了更简单的方法来从接口创建对象,你也应该考虑将你的接口分开,如果你将你的对象用于不同的事情,并且它不会导致接口过度隔离:

interface IBehaviour {
    //Extra
    foo(param: string): void;
}

interface IModal extends IBehaviour{
    content: string;
    form: string;
    //...
}

另一方面,例如在单元测试代码期间(如果您可能不经常应用关注点分离),为了提高效率,您可能能够接受这些缺点。您可以应用其他方法来创建模拟,主要是为大型第三方*.d。ts接口。而且总是为每个巨大的接口实现完全匿名对象可能是一件痛苦的事情。

在这条路径上,你的第一个选择是创建一个空对象:

 var modal = <IModal>{};

其次,充分实现你的界面的强制性部分。无论你是调用第三方JavaScript库,它都是有用的,但我认为你应该创建一个类,就像之前那样:

var modal: IModal = {
    content: '',
    form: '',
    //...

    foo: (param: string): void => {
    }
};

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

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

    }
};

总结一下我的答案,即使接口是可选的,因为它们没有转译成JavaScript代码,TypeScript在那里提供了一个新的抽象级别,如果使用得当和一致的话。我认为,只是因为在大多数情况下你可以在自己的代码中忽略它们,你不应该这样做。

因为我没有在上面找到一个相等的答案,所以我的答案是不同的。 我做的事:

modal: IModal = <IModal>{}