ページへ戻る

− Links

 印刷 

TypeScriptのInterface のソース :: NJF Wiki

xpwiki:TypeScriptのInterfaceのソース

« Prev[3]  
Interfaceというと、他の言語ならクラス定義の型のようなものだが、TypeScriptではより適用範囲が広く、ほとんどの型に適用できる。
おそらく、JavaScriptで起こる型関係のエラーを全部どうにかしたかったのでは無いかと思われる。

このページの内容は公式ページとだいたい同じなので、そちらも参照のこと。[[http://www.typescriptlang.org/Handbook]]

*Interfaceの概要 [#r55fab4b]

Interfaceは要素の存在が指定できるオブジェクトのようなもの。

 function printLabel(labelledObj: {label: string}) {
   console.log(labelledObj.label);
 }
 
 var myObj = {size: 10, label: "Size 10 Object"};
 printLabel(myObj);

もしmyObjにlabelという要素が無いと変換時にエラーとなる。
これによりJavaScript開発でよくある、オブジェクトの中に要素があると思ったらなかったために実行時エラーになるのをあらかじめ防いでくれる。

毎回上のように「{label: string}」と書いていくのは大変なので、よく使うInterfaceは型として定義できる。

 interface LabelledValue {
   label: string;
 }
 
すると次からこれを使って型を指定できる。

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


要素の存在を指定するのがInterfaceの良い所だが、とはいえ実際には使わないかもしれない変数を入れておきたいこともある。そんな時には変数の後ろに「?」を入れる。

 interface LabelledValue {
   label?: string;
 }


要素が無いこともあるので使うときはチェックして使う。

 if(labelledObj.label){
   console.log(labelledObj.label);
 }else{
   console.log("no label");
 }

この場合、要素の存在を保証するという利点は失われるが、エディタの補完がきくのと、タイプミスのチェックが可能という利点は残る。

*関数型 [#s190ccc2]

JavaScriptは変数に関数を入れられるので、コールバック関数の指定などでその機能をよく使うのだが、思ったような関数が入っていなくてエラーとなるというのもよく起こる。TypeScriptのInterfaceは関数型にも対応しているのでそれを防ぐことができる。
関数のInterfaceは「(引数のリスト):戻り値の型」という形式で書ける。

 interface MyFunction{
   (arg1:string,arg2:string):boolean;
 }

これで2つのstring型の引数を持ち、戻り値がbooleanの関数のInterfaceが定義できる。使うときには以下のようにする。

 var myFunc:MyFunction = function(arg1:string,arg2:string):boolean{
   //なにか処理
 }

もちろん、Interfaceで指定した引数と戻り値を持たない関数を入れようとするとエラーとなる。引数名は何でもかまわない。

*配列型 [#xb366d95]

Interfaceには配列も定義できる。添字にはnumberとstringが設定可能。

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

ただし、他の要素を加えるときにはその型が配列の添字と同じでないといけない。

 interface Dictionary {
   [index: string]: string;
   length: number;//stringじゃないのでエラー
 } 

 interface Dictionary {
   [index: string]: string;
   length: string;//stringなのでOK
 }

「[]」でアクセスしたときに矛盾するからと思われる。

*クラス型 [#l97b7524]

クラスの型定義。他の言語でInterfaceという時と同じもの。「implements」で実装する。
 interface ClockInterface {
     currentTime: Date;
     setTime(d: Date);
 }
 
 class Clock implements ClockInterface  {
     currentTime: Date;
     setTime(d: Date) {
         this.currentTime = d;
     }
     constructor(h: number, m: number) { }
 }

**new [#g277fdfe]
newを使うとインスタンス製作時の引数を指定できる。ただし、そのInterfaceを継承するとエラーとなる。

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

これはエラー。

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

こちらはOK。コンストラクタはstaticに属するが、newでチェックするのはインスタンスに属するものなのでエラーが出るらしい。わからないときはJavaScriptのコンストラクタの仕組みを思い出すか、そういう物だと思っておけばよい。

*Interfaceの継承 [#ee044493]

extendsでInterfaceからInterfaceを継承できる。何個でもできる。クラス型で無くてもできる。

 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;

*ハイブリッド型 [#v43f0ff6]

一つのInterfaceをいろいろな型として使える。

 interface Counter {
     (start: number): string;
     interval: number;
     reset(): void;
 }
 
 var c: Counter;
 c(10);//関数型として
 c.reset();//クラス型としてメソッド呼び出し
 c.interval = 5.0;//プロパティ

クラスで良いし、理解しづらいのであまり使われなさそうな気がするが実際どうかは知らない。

« Prev[3]