444

次のようなインターフェイスを定義しました。

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"

インターフェイスを使用してモーダル オブジェクトを記述しても問題ありませんか? もしそうなら、どのように作成すればよいですか?

4

15 に答える 15

588

他の場所で「モーダル」変数を作成していて、TypeScript にすべてが完了するように伝えたい場合は、次を使用します。

declare const modal: IModal;

TypeScript で実際に IModal のインスタンスになる変数を作成する場合は、それを完全に定義する必要があります。

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

または、型アサーションを使用して嘘をつきますが、予期しない場所で未定義になるため、型の安全性が失われ、アクセス時などに実行時エラーが発生する可能性がありますmodal.content(コントラクトがそこにあると言うプロパティ)。

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();
于 2012-10-30T15:52:59.560 に答える
243

If you want an empty object of an interface, you can do just:

var modal = <IModal>{};

The advantage of using interfaces in lieu of classes for structuring data is that if you don't have any methods on the class, it will show in compiled JS as an empty method. Example:

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

compiles into

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

which carries no value. Interfaces, on the other hand, don't show up in JS at all while still providing the benefits of data structuring and type checking.

于 2014-06-16T19:37:54.633 に答える
23

できるよ

var modal = {} as IModal 
于 2017-12-03T10:26:25.077 に答える
22

そうするために、基本的に5つの異なるオプションがあると思います。達成したい目標に応じて、それらの中から選択するのは簡単です。

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 は新しいレベルの抽象化を提供するために存在します。ほとんどの場合、独自のコードからそれらを却下できるからといって、そうすべきではないと思います。

于 2015-12-13T17:59:23.680 に答える