首页 文章

如何基于TypeScript中的接口文件定义创建对象?

提问于
浏览
190

我已经定义了这样的界面:

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

我定义了一个这样的变量:

var modal: IModal;

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

"cannot set property content of undefined"

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

7 回答

  • 1

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

    declare const modal: IModal;
    

    如果要在TypeScript中创建实际上是IModal实例的变量,则需要完全定义它 .

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

    或者说谎,使用类型断言,但是你将失去类型安全性,因为你现在将在意外的地方得到未定义,并且可能在访问 modal.content 时出现运行时错误等等( Contract 说明的那些属性) .

    const modal = {} as IModal;
    

    Example Class

    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();
    
  • 15

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

    var modal = <IModal>{};
    

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

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

    汇编成

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

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

  • 30

    如果您正在使用React,解析器将阻塞传统的强制转换语法,因此引入了替代方法以在.tsx文件中使用

    let a = {} as MyInterface;
    

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

  • 139

    我认为你基本上已经 five different options 这样做了 . 根据您希望实现的目标,在其中进行选择可能很容易 .

    在大多数情况下,最好的方法是 use a class and instantiate it ,因为您正在使用TypeScript来应用类型检查 .

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

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

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

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

    在这条路径上,您的第一个选择是 create an empty object

    var modal = <IModal>{};
    

    其次是 fully realise the compulsory part of your interface . 无论您是在调用第三方JavaScript库,都会很有用,但我认为您应该创建一个类,就像之前一样:

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

    第三,你只需创建 part of your interface 并创建一个 anonymous object ,但这样你就有责任履行 Contract

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

    即使接口是可选的,总结我的答案,因为它们不会被转换为JavaScript代码,如果明智且一致地使用,TypeScript可以提供新的抽象级别 . 我想,只是因为你可以在大多数情况下从你自己的代码中解雇它们,你不应该这样做 .

  • 9

    你可以做

    var modal = {} as IModal
    
  • 257

    由于我没有在顶部找到相同的答案,我的答案是不同的,我这样做:

    modal: IModal = <IModal>{}

  • 4

    使用您的界面即可

    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.
    }
    }
    

相关问题