【Type Script】Type Script学習2——インターフェース

10686 ワード

Type Scriptでは、インターフェースは制約の役割として使われています.JavaScriptにコンパイルされると、すべてのインターフェースは消去されます.JavaScriptにはインターフェースという概念がないからです.
まず簡単な例を見てください.
function printLabel(labelledObj: { label: string }) {
    console.log(labelledObj.label);
}

var myObj = { size: 10, label: "Size 10 Object" };
printLabel(myObj);
この方法では、labelledObjのタイプは「label:string」というもので、複雑に見えるかもしれませんが、次のmyObjの声明を見てわかります.これはsize属性(値は10)とlabel属性(値は「Size 10 Object」)を持つ対象を宣言したものです.したがって、方法パラメータlabelledObjのタイプは、パラメータがstringタイプのlabel属性を持つことを示す.
しかし、このように書くと、この方法はまだ少し分かりません.この方法のパラメータタイプはインタフェースで定義できます.
interface LabelledValue {
    label: string;
}

function printLabel(labelledObj: LabelledValue) {
    console.log(labelledObj.label);
}

var myObj = { size: 10, label: "Size 10 Object" };
printLabel(myObj);
  • オプション属性
  • いくつかの場合、属性が必ず存在する必要はなく、オプション属性という特性を使って定義することができます.
    interface SquareConfig {
        color?: string;
        width?: number;
    }
    
    function createSquare(config: SquareConfig): { color: string; area: number } {
        var newSquare = { color: "white", area: 100 };
        if (config.color) {
            newSquare.color = config.color;
        }
        if (config.width) {
            newSquare.area = config.width * config.width;
        }
        return newSquare;
    }
    
    var mySquare = createSquare({ color: "black" });
    Square Configインターフェースを実現するためのオブジェクトcreateSquare法を導入しました.
    完全にあってもなくてもいいのに、なぜ定義が必要ですか?完全に定義されていないよりもオプション属性を定義することには二つの利点がある.1、属性があれば、タイプを制約することができます.これは非常に重要です.2、文法知能の提示が得られます.もし方法体の中のカラーをハローと間違えたら、コンパイルはいけません.
  • メソッドタイプ
  • JavaScriptでは、メソッドfunctionは基本的なタイプです.対象に向かう思想の中で、インターフェースの実現は種類によって達成して、functionは1種のタイプとして、インターフェースを実現することができるのではありませんか?答えは肯定的です.
    Type Scriptでは,方法の署名を制約するためにインタフェースを使用することができる.
    interface SearchFunc {
      (source: string, subString: string): boolean;
    }
    var mySearch: SearchFunc;
    mySearch = function(source: string, subString: string) {
      var result = source.search(subString);
      if (result == -1) {
        return false;
      }
      else {
        return true;
      }
    }
    上記のコードでは、2つの文字列パラメータがあり、ブール値を返します.第二のセグメントコードではこのインターフェースの実現を宣言した.
    なお、コンパイラはタイプが正しいかどうか(パラメータタイプ、戻り値タイプ)だけをチェックしますので、パラメータの名前は他のものに変えられます.
    var mySearch: SearchFunc;
    mySearch = function(src: string, sub: string) {
      var result = src.search(sub);
      if (result == -1) {
        return false;
      }
      else {
        return true;
      }
    }
    これもコンパイルできます.
  • 配列タイプ
  • 上記のインターフェースで方法の種類を定義しましたが、配列の種類はどう定義すればいいですか?簡単です
    interface StringArray {
      [index: number]: string;
    }
    
    var myArray: StringArray;
    myArray = ["Bob", "Fred"];
    myArayは配列であり、インデックスはnumberタイプであり、要素はstringである.
    インターフェースの定義では、インデックスの名前は一般的にindexとなります.ということで
    interface StringArray {
      [myIndex: number]: string;
    }
    
    var myArray: StringArray;
    myArray = ["Bob", "Fred"];
    それもokです
    インデックスのタイプはnumberまたはstringだけです.
    interface Array{
        [index: number]: any;
    }
    
    interface Dictionary{
        [index: string]: any;
    }
    上の二段は全部コンパイルして通ります.
    最後にもう一つの注意点がありますが、インターフェースがすでに配列タイプである場合、インターフェースで定義されている他の属性のタイプは全てこの配列の要素タイプでなければなりません.たとえば:
    interface Dictionary {
      [index: string]: string;
      length: number;    // error, the type of 'length' is not a subtype of the indexer
    }
    コンパイルできなくなります.lengthをstringタイプに変更しなければなりません.
  • クラス実現インターフェース
  • を使用する.
    一般的に、私達はやはり1つの種類を使うことに慣れて、必要なインターフェースを実現して、上のように直接インターフェースを使いません.
    interface ClockInterface {
        currentTime: Date;
    }
    
    class Clock implements ClockInterface  {
        currentTime: Date;
        constructor(h: number, m: number) { }
    }
    Type Scriptでは、クラスのキーワードを使って声明しています.これはEcmaScript 6と同じです.
    さらに,クラスで定義された方法を制約するために界面を使用することができる.
    interface ClockInterface {
        currentTime: Date;
        setTime(d: Date);
    }
    
    class Clock implements ClockInterface  {
        currentTime: Date;
        setTime(d: Date) {
            this.currentTime = d;
        }
        constructor(h: number, m: number) { }
    }
    Type Scriptでは,界面のために構造関数を定義することができます.
    interface ClockInterface {
        new (hour: number, minute: number);
    }
    続いて無邪気な私達はこのように書くかもしれません.
    interface ClockInterface {
        new (hour: number, minute: number);
    }
    
    class Clock implements ClockInterface  {
        currentTime: Date;
        constructor(h: number, m: number) { }
    }
    これはいけません!!コンストラクタはstatic(静的)であり、クラスはインターフェースのinstance(例)部分だけを実現することができるからである.
    このインターフェースで定義されているコンストラクタは機能しないのではないですか?Type Scriptがこの機能を提供している以上、きっと機能がないはずです.宣言の方法は特殊です.
    interface ClockStatic {
        new (hour: number, minute: number);
    }
    
    class Clock  {
        currentTime: Date;
        constructor(h: number, m: number) { }
    }
    
    var cs: ClockStatic = Clock;
    var newClock = new cs(7, 30);
    普通はnew Clockと書いていますが、ここでClockクラスをClock Stticインターフェースに指します.なお、newClock変数の種類はanyである.
  • 継承インターフェース
  • クラスのようにインターフェースも継承できます.extendsのキーワードを使っています.
    interface Shape {
        color: string;
    }
    
    interface Square extends Shape {
        sideLength: number;
    }
    
    var square = <Square>{};
    square.color = "blue";
    square.sideLength = 10;
    もちろん、複数のインターフェースを継承することもできます.
    interface Shape {
        color: string;
    }
    
    interface PenStroke {
        penWidth: number;
    }
    
    interface Square extends Shape, PenStroke {
        sideLength: number;
    }
    
    var square = <Square>{};
    square.color = "blue";
    square.sideLength = 10;
    square.penWidth = 5.0;
    なお、複数のインターフェースの継承をサポートしていますが、継承インターフェースで定義された同名属性のタイプが異なるとコンパイルできません.
    interface Shape {
        color: string;
        test: number;
    }
    
    interface PenStroke {
        penWidth: number;
        test: string;
    }
    
    interface Square extends Shape, PenStroke {
        sideLength: number;
    }
    このコードはコンパイルできません.test属性のタイプが確定できないからです.
  • は、上記のタイプ
  • を同時に使用する.
    単一のタイプしか使えないなら、このインターフェースはあまりにも弱いです.幸いなことに、私たちのインターフェースはとても強いです.
    interface Counter {
        (start: number): string;
        interval: number;
        reset(): void;
    }
    
    var c: Counter;
    c(10);
    c.reset();
    c.interval = 5.0;
    このように3つのタイプに使用され、それぞれ方法(インターフェース自体が方法)、属性、方法(方法メンバーを定義している)である.