星期三, 2月 15, 2017

TypeScript 學習筆記(5) – Interface

今天是看這篇:Interfaces
TypeScript 有 anonymous interface ,就像下面的程式一樣:
// 有點 anonymous interface 的味道
function printLabel1(labelledObj: { label: string }) {
    console.log(labelledObj.label);
}

// 也可以明確的用 interface 寫
interface LabelledValue {
    label: string;
}

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

在宣告成員時,如果加入 ? ,表示可有可無,這個寫法應該是參考了 Ruby 的作法
interface SquareConfig {
    color?: string;
    width?: number;
}

用 readonly 修飾詞則是表示唯讀
interface Point {
    readonly x: number;
    readonly y: number;
}

如果要需告一個唯讀的陣列,可以用 ReadonlyArray
let ro: ReadonlyArray = a;

我覺得 Function types 比較不是那麼直覺,不容易看懂
interface SearchFunc {
    (source: string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
    let result = source.search(subString);
    return result > -1;
}
大抵來說就是 python 的 \__call\__ 或是 c++ 的 operator()。
Indexable type 也是不太直覺
interface StringArray {
    [index: number]: string;
}

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

let myStr: string = myArray[0];
大抵來說就是 python 的 \__item\__ 或是 c++ 的 operator[]。
要讓類別實作介面是用 implements 關鍵字
interface ClockInterface {
    currentTime: Date;
}

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

下面這例子是想要限定 ClockInterface 裡的 constructor 必須符合 ClockConstructor 規範的作法,第一眼不太容易看懂。

interface ClockConstructor {
    new (hour: number, minute: number): ClockInterface;
}
interface ClockInterface {
    tick();
}

// 傳進來的 ctor 必須符合 ClockConstructor 的規範,要有 hour 跟 minute 這兩個 number 型別的參數。
function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface {
    return new ctor(hour, minute);
}

class DigitalClock implements ClockInterface {
    constructor(h: number, m: number) { }
    tick() {
        console.log("beep beep");
    }
}
class AnalogClock implements ClockInterface {
    constructor(h: number, m: number) { }
    tick() {
        console.log("tick tock");
    }
}

let digital = createClock(DigitalClock, 12, 17);
let analog = createClock(AnalogClock, 7, 32);

介面也可以繼承,跟類別一樣,是用 extends,而且允許繼承多個
interface Shape {
    color: string;
}
interface PenStroke {
    penWidth: number;
}
interface Square extends Shape, PenStroke {
    sideLength: number;
}

蠻令我驚訝的是,Interface 可以繼承 class ... @_@

沒有留言: