ホームページ > ウェブフロントエンド > jsチュートリアル > TypeScript_javascriptスキルのインターフェースの詳細説明

TypeScript_javascriptスキルのインターフェースの詳細説明

WBOY
リリース: 2016-05-16 15:54:07
オリジナル
1594 人が閲覧しました

TypeScript では、インターフェイスは制約として使用されます。JavaScript にはインターフェイスの概念がないため、JavaScript にコンパイルされると、すべてのインターフェイスが消去されます。

簡単な例を見てみましょう:

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

var myObj = { size: 10, label: "Size 10 Object" };
printLabel(myObj);

ログイン後にコピー

このメソッドでは、labeledObj の型は {label: string} となっており、少し複雑に見えるかもしれませんが、以下の myObj の宣言を見ると、これが size 属性 (値は 10)、ラベル属性を持つオブジェクト (値は「サイズ 10 オブジェクト」)。したがって、メソッド パラメータ labeledObj の型は {label: string} です。これは、パラメータが 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" });

ログイン後にコピー

次に、SquareConfig インターフェイスを実装するオブジェクトを createSquare メソッドに渡します。

それは完全に必要不可欠なものであるのに、なぜそれを定義する必要があるのでしょうか?オプションのプロパティを定義すると、まったく定義しない場合と比べて 2 つの利点があります。 1. 属性がある場合、型が制限される可能性があります。これは非常に重要です。2. メソッド本体に誤って color を color として記述すると、コンパイルが失敗します。

メソッドタイプ

JavaScript ではメソッド関数が基本型です。オブジェクト指向の考え方では、インターフェイスの実装はクラスによって実現されますが、関数はインターフェイスを実装できますか?答えは「はい」です。

TypeScript では、インターフェイスを使用してメソッドのシグネチャを制約できます。

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 つの文字列パラメータがあり、ブール値を返します。コードの 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"];

ログイン後にコピー

myArray は配列であり、インデクサーの型は数値であり、要素は文字列です。

インターフェイスの定義では、インデクサーの名前は通常、index です (もちろん、他の名前に変更することもできますが、通常は名前がインデックスのままになります)。したがって、それを

に変更します
interface StringArray {
 [myIndex: number]: string;
}

var myArray: StringArray;
myArray = ["Bob", "Fred"];

ログイン後にコピー

それもOKです。

インデクサーのタイプは数値または文字列のみであることに注意してください。

interface Array{
  [index: number]: any;
}

interface Dictionary{
  [index: string]: any;
}

ログイン後にコピー

上記の 2 つの段落はコンパイルして渡すことができます。

最後に注意すべきことは、インターフェイスがすでに配列型である場合、インターフェイスで定義されている他の属性の型は配列の要素型である必要があるということです。例:

interface Dictionary {
 [index: string]: string;
 length: number;  // error, the type of 'length' is not a subtype of the indexer
}
ログイン後にコピー

この場合、コンパイルされず、長さを文字列型に変更する必要があります。

クラスを使用してインターフェースを実装する
通常の状況では、上記のようにインターフェイスを直接使用するのではなく、クラスを使用して必要なインターフェイスを実装することに慣れています。

interface ClockInterface {
  currentTime: Date;
}

class Clock implements ClockInterface {
  currentTime: Date;
  constructor(h: number, m: number) { }
}

ログイン後にコピー

TypeScript では、class キーワードを使用して宣言します。これは 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) { }
}

ログイン後にコピー

TypeScript では、インターフェイスのコンストラクターを定義できます。

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) { }
}

ログイン後にコピー

これではうまくいきません! ! !コンストラクターは静的であるため、クラスはインターフェイスのインスタンス部分のみを実装できます。

では、このインターフェースで定義されたコンストラクターは効果がないのでしょうか? TypeScript はこの機能を提供するため、決して役に立たないわけではありません。宣言されたメソッドはかなり特殊です:

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);

ログイン後にコピー

通常は新しい Clock を作成しますが、ここでは Clock クラスを ClockStatic インターフェイスに指定します。 newClock変数の型は任意であることに注意してください。

継承されたインターフェース
クラスと同様に、インターフェイスでも 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;

ログイン後にコピー

这样就使用到三种类型了,分别是方法(接口自己是个方法)、属性、方法(定义了方法成员)。

以上所述就是本文的全部内容了,希望大家能够喜欢。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート