interfaceについて

インタフェース

interface SquareConfig {
    color?: string;
    width?: number;
}

function execute(config: SquareConfig): void {
    console.log(config);
}

// implementsする必要はなくて、型チェッカーはプロパティが一致してるかをチェックする
execute({ color: 'red', width: 100 });

型チェッカー

インタフェースに未定義のプロパティを指定すると、型チェッカーによりエラーが発生する

// error TS2345: Argument of type '{ height: number; width: number; }' is not assignable to parameter of type 'SquareConfig'.
// Object literal may only specify known properties, and 'height' does not exist in type 'SquareConfig'.
execute({ height: 100, width: 100 });

このエラーは型注釈(type assertion)を指定することで回避できる

execute({ height: 100, width: 100 } as SquareConfig);

Function型

interface SearchFunc {
    (source: string, subString: string): boolean;
}

let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
    let result = source.search(subString);
    if (result == -1) {
        return false;
    }
    else {
        return true;
    }
}

シグネチャが不一致だとエラーとなる

// error TS2322: Type '(source: string, subString: string, extra: number) => boolean' is not assignable to type 'SearchFunc'.
let mySearch2: SearchFunc;
mySearch2 = function(source: string, subString: string, extra: number) {
    return true;
}
デフォルト値
interface SampleFunc {
    (a?: string, b?: string): void;
}

let mySample: SampleFunc;
mySample = function(a = "goo", b = "foo") {
    console.log(`a = ${a}, b= ${b}`);
}

mySample(); // a = goo, b= foo を出力
mySample("1"); // a = 1, b= foo を出力
mySample("1", "2"); // a = 1, b= 2 を出力

インデックス可能な型

使い道がわからない、、

interface StringArray {
    [index: number]: string;
}
let myArray: StringArray = ["Bob", "Fred"];
let myStr: string = myArray[0];
console.log(myStr);

インターフェースの実装

interface ClockInterface {
    currentTime: Date;
    getTime(): Date;
    setTime(d: Date): void;
}
class Clock implements ClockInterface {
    currentTime: Date;
    getTime(): Date {
        return this.currentTime;
    }
    setTime(d: Date): void {
        this.currentTime = d;
    }
    constructor(d = new Date()) {
        this.currentTime = d;
    }
}

インターフェースの拡張

interface Shape {
    color: string;
}
interface PenStroke {
    penWidth: number;
}
interface Square extends Shape, PenStroke {
    sideLength: number;
}
let square = {} as Square;
square.color = "blue";
square.sideLength = 10;
square.penWidth = 5.0;

インターフェースのマージ

同じ Interface を再宣言すると Interface 同士がマージされる

interface IHoge {
    goo: number;
}

interface IHoge {
    foo: string;
}

const a: IHoge = {
    goo: 1,
    foo: "abc"
};

// gooが未定義のためコンパイルエラー
// error TS2741: Property 'goo' is missing in type '{ foo: string; }' but required in type 'IHoge'.
const b: IHoge = {
    foo: "abc"
};