TypeScript 接口

TypeScript
接口

接口只讀屬性

使用關(guān)鍵字readonly定義只讀的接口屬性

interface Point {
    readonly x: number;
    readonly y: number;
}
// 定義一個接口
interface Point{
    readonly x: number;
    readonly y: number;
}

// 對接口賦值
let p1: Point = { x: 10, y: 20 };
p1.x = 5;   // 該句錯誤疑务,不能進行賦值操作

出現(xiàn)錯誤宝与,如下


image

創(chuàng)建不可修改的數(shù)組

image
// 定義一個接口
interface Point{
    readonly x: number;
    readonly y: number;
}

// 對接口賦值
let p1: Point = { x: 10, y: 20 };
//p1.x = 5; // 該句錯誤,不能進行賦值操作

let a: number[] = [1, 2, 3, 4, 5];
let ro: ReadonlyArray<number> = a;  // 設(shè)置為只讀的數(shù)組
ro[0] = 12; // 不可進行賦值捉捅。出現(xiàn)賦值錯誤

如果想要重新賦值撤防,斷言重寫

當(dāng)一個值有多個類型的時候,使用斷言重寫棒口,確定一個新的類型

// 定義一個接口
interface Point{
    readonly x: number;
    readonly y: number;
}

// 對接口賦值
let p1: Point = { x: 10, y: 20 };
//p1.x = 5; // 該句錯誤寄月,不能進行賦值操作

let a = [2, 3, 4, 5];
let ro: ReadonlyArray<number> = [2, 3, 4, 5];
//ro[0] = 12;   // 不可進行賦值
// 如果需要賦值,使用斷言重寫
a = ro as number[]; // 進行斷言重寫

// 對接口賦值
var p1 = { x: 10, y: 20 };
//p1.x = 5; // 該句錯誤无牵,不能進行賦值操作
var a = [2, 3, 4, 5];
var ro = [2, 3, 4, 5];
//ro[0] = 12;   // 不可進行賦值
// 如果需要賦值漾肮,使用斷言重寫
a = ro; // 進行斷言重寫
//# sourceMappingURL=out.js.map

類型斷言很大程度上可以規(guī)范類型

函數(shù)類型的接口

// 定義一個函數(shù)類型的接口
interface SearchFunc {
    (source: string, subString: string): boolean;   // 定義一個函數(shù)類型的接口
}

// 使用這個接口
let mySearch: SearchFunc;
mySearch = (source:string,subString:string) => {
    let result = source.search(subString);  // 兩個字符串正則匹配
    return result > -1;
}
// 使用這個接口
var mySearch;
mySearch = function (source, subString) {
    var result = source.search(subString); // 兩個字符串正則匹配
    return result > -1;
};
//# sourceMappingURL=out.js.map

編譯器會逐個檢查,如果統(tǒng)統(tǒng)正確茎毁,則編譯通過克懊,否則編譯不通過

定義索引接口

// 定義索引接口
interface StringArray {
    [index: number]: string;
}

let myArray: StringArray;   // 定義一個myArray的變量,類型為索引接口
myArray = ["Bob", "Fred"];

let myStr: string = myArray[0]; // 取第一個值

var myArray; // 定義一個myArray的變量,類型為索引接口
myArray = ["Bob", "Fred"];
var myStr = myArray[0]; // 取第一個值
//# sourceMappingURL=out.js.map

索引值內(nèi)部必須全部為number類型的


image
// 定義接口,一個索引值類型的保檐,其返回值也為索引類型的
interface NumberDictionary{
    [index: string]: number;
    length: number; // 可以設(shè)置length
    name: string;   // 錯誤索引值內(nèi)部不能擁有string類型
}

編譯一下出現(xiàn)錯誤

索引簽名依舊可以設(shè)置為只讀耕蝉,此時可以防止給索引賦值。使用關(guān)鍵字readonly

// 定義接口
interface NumberDictionary {
    readonly [index: number]: string;
}

// 初始化一個變量
let myArray: NumberDictionary = ["hello", "world"];

順帶配置一下配置文件

// tsconfig.json
{
    "compilerOptions": {
        "out": "built/out.js", 
        "sourceMap": true, 
        "target": "es5"
    }, 
    "files": [
        "greeter.ts"
    ]
}
// out.js
// 初始化一個變量
var myArray = ["hello", "world"];
//# sourceMappingURL=out.js.map
// 定義接口
interface NumberDictionary {
    readonly [index: number]: string;
}

// 初始化一個變量
let myArray: NumberDictionary = ["hello", "world"];

// 此時進行賦值為錯誤的
myArray[2] = "hello world";

類類型

明確一個類去符合一種接口

// 定義接口
interface ClockInterFace {
    currentTime: Date;
}

class Clock implements ClockInterFace { // 使用implements 關(guān)鍵字clock類符合接口clockInterFace
    currentTime: Date;
    constructor(h:number, m:number){
        // 定義構(gòu)造函數(shù)
    }
}

// 注意在上方中并不會對靜態(tài)的夜只,進行檢查垒在。只會對非靜態(tài)的部分,即非構(gòu)造函數(shù)部分進行檢查

var Clock = /** @class */ (function () {
    function Clock(h, m) {
        // 定義構(gòu)造函數(shù)
    }
    return Clock;
}());
//# sourceMappingURL=out.js.map

如果配置成為es6即

{
    "compilerOptions": {
        "out": "built/out.js", 
        "sourceMap": true, 
        "target": "es6"
    }, 
    "files": [
        "greeter.ts"
    ]
}
class Clock {
    constructor(h, m) {
        // 定義構(gòu)造函數(shù)
    }
}
//# sourceMappingURL=out.js.map

接口描述方法扔亥,類實現(xiàn)

interface ClockInterface {
    currentTime: Date;
    setTime(d: Date);   // 定義接口的方法
}

class Clock implements ClockInterface{
    currentTime: Date;  // 接口檢查的
    setTime(d:Date){    // 接口檢查的方法
        this.currentTime = d;
    }
    constructor(h:number, m:number){    // 接口不會檢查靜態(tài)的構(gòu)造方法

    }
}
var Clock = /** @class */ (function () {
    function Clock(h, m) {
    }
    Clock.prototype.setTime = function (d) {
        this.currentTime = d;
    };
    return Clock;
}());
//# sourceMappingURL=out.js.map

關(guān)于構(gòu)造函數(shù)的接口

構(gòu)造函數(shù)屬于靜態(tài)的方法场躯,當(dāng)構(gòu)造器定義了一個靜態(tài)的方法的時候。構(gòu)造器只檢查動態(tài)的方法旅挤,并不會檢查動態(tài)的方法踢关,故,下方的寫法編譯器不通過

interface ClockConstructor {
    new (hour: number, minuter: number);    // 定義構(gòu)造函數(shù)的接口
};

class clock implements ClockConstructor {
    currenTime: Date;
    constructor(h:number, m:number){    // 接口限制的是此構(gòu)造函數(shù)

    }
}interface ClockConstructor {
    new (hour: number, minuter: number);    // 定義構(gòu)造函數(shù)的接口
};

class clock implements ClockConstructor {
    currenTime: Date;
    constructor(h:number, m:number){    // 接口限制的是此構(gòu)造函數(shù)

    }
}interface ClockConstructor {
    new (hour: number, minuter: number);    // 定義構(gòu)造函數(shù)的接口
};

class clock implements ClockConstructor {
    currenTime: Date;
    constructor(h:number, m:number){    // 接口限制的是此構(gòu)造函數(shù)

    }
}interface ClockConstructor {
    new (hour: number, minuter: number);    // 定義構(gòu)造函數(shù)的接口
};

class clock implements ClockConstructor {
    currenTime: Date;
    constructor(h:number, m:number){    // 接口限制的是此構(gòu)造函數(shù)

    }
}interface ClockConstructor {
    new (hour: number, minuter: number);    // 定義構(gòu)造函數(shù)的接口
};

class clock implements ClockConstructor {
    currenTime: Date;
    constructor(h:number, m:number){    // 接口限制的是此構(gòu)造函數(shù)

    }
}interface ClockConstructor {
    new (hour: number, minuter: number);    // 定義構(gòu)造函數(shù)的接口
};

class clock implements ClockConstructor {
    currenTime: Date;
    constructor(h:number, m:number){    // 接口限制的是此構(gòu)造函數(shù)

    }
}

編譯

PS C:\Users\mingm\Desktop\ts> tsc
Active code page: 65001
greeter.ts:5:7 - error TS2420: Class 'clock' incorrectly implements interface 'ClockConstructor'.
  Type 'clock' provides no match for the signature 'new (hour: number, minuter: number): any'.

5 class clock implements ClockConstructor {
        ~~~~~

PS C:\Users\mingm\Desktop\ts>

出現(xiàn)錯誤

解決粘茄,既然不會對靜態(tài)的構(gòu)造方法進行檢查签舞,那就在創(chuàng)建一個接口,進行更進一步的靜態(tài)方法的檢查柒瓣。
即儒搭,創(chuàng)建一個接口,返回一個接口芙贫,這樣就會對該構(gòu)造方法進行檢查搂鲫。

類似于類和父類的關(guān)系,子類磺平,父類魂仍,超類,超類會返回一個類拣挪,會調(diào)用超類的構(gòu)造方法擦酌,生成子類,此時在這個過程中會進行接口的檢查菠劝。

// 定義一個用于檢查構(gòu)造函數(shù)的接口仑氛,該接口需要返回一個接口
interface ClockConstructor{
    new (hour: number, minute: number): ClockInterface;
}
// 繼續(xù)定義一個接口,該接口接收來自上一個接口返回的內(nèi)容闸英,進行驗證
interface ClockInterface {
    tick(); 
}
// 創(chuàng)建一個函數(shù),返回一個函數(shù)(該函數(shù)再次執(zhí)行)
function createClock(ctor: ClockConstructor, hour:number, minute:number):ClockInterface{
    return new ctor(hour, minute);  
}

// 定義一個類
class DigitalClock implements ClockInterface {  // 下層接口
    constructo(h: number, m: number) { };
    tick(){
        console.log("=橥唷8巍!");
    }
}

// 定義一個類
class AnalogClock implements ClockInterface {
    constructor(h: number, m: number) { };
    tick(){
        console.log("!!!!!!!!");
    }
}

// 調(diào)用租函數(shù)遇伞,傳入一個類辙喂,返回一個對象
let digital = createClock(DigitalClock, 12, 17);
let analog = createClock(AnalogClock, 2, 4);

上方的核心在于創(chuàng)建了兩個接口,一個接口用于檢查父的內(nèi)容,一個接口用于進行創(chuàng)建對象進行驗證巍耗。父的擁有一個函數(shù)秋麸,傳入一個類,并對其進行檢查炬太。

// 創(chuàng)建一個函數(shù)灸蟆,返回一個函數(shù)(該函數(shù)再次執(zhí)行)
function createClock(ctor, hour, minute) {
    return new ctor(hour, minute); // 
}
// 定義一個類
var DigitalClock = /** @class */ (function () {
    function DigitalClock() {
    }
    DigitalClock.prototype.constructo = function (h, m) { };
    ;
    DigitalClock.prototype.tick = function () {
        console.log("!G鬃濉炒考!");
    };
    return DigitalClock;
}());
// 定義一個類
var AnalogClock = /** @class */ (function () {
    function AnalogClock(h, m) {
    }
    ;
    AnalogClock.prototype.tick = function () {
        console.log("!!!!!!!!");
    };
    return AnalogClock;
}());
// 調(diào)用租函數(shù),傳入一個類霎迫,返回一個對象
var digital = createClock(DigitalClock, 12, 17);
var analog = createClock(AnalogClock, 2, 4);
//# sourceMappingURL=out.js.map
// 創(chuàng)建一個函數(shù)斋枢,返回一個函數(shù)(該函數(shù)再次執(zhí)行)
function createClock(ctor, hour, minute) {
    return new ctor(hour, minute); // 此處類似于js中的閉包問題
}
// 定義一個類
class DigitalClock {
    constructo(h, m) { }
    ;
    tick() {
        console.log("!V瓤帚!");
    }
}
// 定義一個類
class AnalogClock {
    constructor(h, m) { }
    ;
    tick() {
        console.log("!!!!!!!!");
    }
}
// 調(diào)用租函數(shù),傳入一個類涩赢,返回一個對象
let digital = createClock(DigitalClock, 12, 17);
let analog = createClock(AnalogClock, 2, 4);
//# sourceMappingURL=out.js.map

繼承接口

類能繼承戈次,那么接口也能繼承

// 接口
interface Shape {
    color: string;
}
// 一個繼承接口
interface Square extends Shape {
    sideLength: number; 
}

let square = {} as Square;  //類型斷言
square.color = "blue";
square.sideLength = 10; 

var square = {}; //類型斷言
square.color = "blue";
square.sideLength = 10;
//# sourceMappingURL=out.js.map

也可以進行從多個接口繼承,即創(chuàng)造出合成接口

interface Shape{
    color: string;
}

interface penStroke{
    penWidth: number;
}

// 從兩個接口繼承而來的接口
interface Square extends Shape, penStroke{
    sideLength: number;
}

let square = <Square>{};
square.color = "blue";
square.sideLength = 10;
square.penWidth = 5.0;
var square = {};
square.color = "blue";
square.sideLength = 10;
square.penWidth = 5.0;
//# sourceMappingURL=out.js.map

混合類型

對象既可為函數(shù)谒主,又可為對象

interface Counter {
    (start: number): string;    // 函數(shù)
    interval: number;
    reset(): void;
}

// 下面將會書寫閉包
function getConter():Counter{   // 返回將會是一個接口類型的
    let counter = <Counter>function (start: number){};  // 類型斷言
    counter.interval = 123;
    counter.reset = () => { };
    return counter; // 返回一個函數(shù)
}

let c = getConter();
c(10);
c.reset();
c.interval = 5.0;
// 下面將會書寫閉包
function getConter() {
    var counter = function (start) { }; // 類型斷言
    counter.interval = 123;
    counter.reset = function () { };
    return counter; // 返回一個函數(shù)
}
var c = getConter();
c(10);
c.reset();
c.interval = 5.0;
//# sourceMappingURL=out.js.map

接口繼承類

接口繼承類時朝扼,會繼承類成員,但不包含其實現(xiàn)霎肯。
即擎颖,接口聲明了類中的成員,但并沒有提供具體的實現(xiàn)观游。
接口同樣會繼承private(私有的)搂捧,和protected(對于本包和子同樣可見)

根據(jù)上述的說明,可以知道懂缕,當(dāng)一個接口允跑,繼承自擁有protected的類的時候,此時該接口只能被子類搪柑,或者該類使用聋丝。

image
class Control {
    private state: any; // 定義一個任何類型的私有屬性
}

// 定義一個接口,該接口繼承自Control
interface SelectableControl extends Control {
    select(): void;
}

// 定義一個子類工碾,該類繼承自Control,并使用接口SelectableControl弱睦,由于是子類,可以使用SelectableControl接口
class Button extends Control implements SelectableControl {
    select() { };
}

// 定義一個子類該類繼承自Control
class TextBox extends Control {
    select(){}
}

// 定義一個Image類渊额,該類不能使用SelectableControl接口
//class Image implements SelectableControl{

//}

// 和其余類沒有任何繼承關(guān)系的類
class Liaction {

}

es5 js如下

var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    }
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var Control = /** @class */ (function () {
    function Control() {
    }
    return Control;
}());
// 定義一個子類况木,該類繼承自Control,并使用接口SelectableControl垒拢,由于是子類,可以使用SelectableControl接口
var Button = /** @class */ (function (_super) {
    __extends(Button, _super);
    function Button() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    Button.prototype.select = function () { };
    ;
    return Button;
}(Control));
// 定義一個子類該類繼承自Control
var TextBox = /** @class */ (function (_super) {
    __extends(TextBox, _super);
    function TextBox() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    TextBox.prototype.select = function () { };
    return TextBox;
}(Control));
// 定義一個Image類火惊,該類不能使用SelectableControl接口
//class Image implements SelectableControl{
//}
// 和其余類沒有任何繼承關(guān)系的類
var Liaction = /** @class */ (function () {
    function Liaction() {
    }
    return Liaction;
}());
//# sourceMappingURL=out.js.map
PS C:\Users\mingm\Desktop\ts> tsc
Active code page: 65001
PS C:\Users\mingm\Desktop\ts>

es6如下

class Control {
}
// 定義一個子類求类,該類繼承自Control,并使用接口SelectableControl,由于是子類屹耐,可以使用SelectableControl接口
class Button extends Control {
    select() { }
    ;
}
// 定義一個子類該類繼承自Control
class TextBox extends Control {
    select() { }
}
// 定義一個Image類尸疆,該類不能使用SelectableControl接口
//class Image implements SelectableControl{
//}
// 和其余類沒有任何繼承關(guān)系的類
class Liaction {
}
//# sourceMappingURL=out.js.map
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市张症,隨后出現(xiàn)的幾起案子仓技,更是在濱河造成了極大的恐慌,老刑警劉巖俗他,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脖捻,死亡現(xiàn)場離奇詭異,居然都是意外死亡兆衅,警方通過查閱死者的電腦和手機地沮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來羡亩,“玉大人摩疑,你說我怎么就攤上這事∥访” “怎么了雷袋?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長辞居。 經(jīng)常有香客問我楷怒,道長,這世上最難降的妖魔是什么瓦灶? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任鸠删,我火速辦了婚禮,結(jié)果婚禮上贼陶,老公的妹妹穿的比我還像新娘刃泡。我一直安慰自己,他們只是感情好碉怔,可當(dāng)我...
    茶點故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布烘贴。 她就那樣靜靜地躺著,像睡著了一般撮胧。 火紅的嫁衣襯著肌膚如雪桨踪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天趴樱,我揣著相機與錄音馒闷,去河邊找鬼。 笑死叁征,一個胖子當(dāng)著我的面吹牛纳账,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播捺疼,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼疏虫,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了啤呼?” 一聲冷哼從身側(cè)響起卧秘,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎官扣,沒想到半個月后翅敌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡惕蹄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年蚯涮,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片卖陵。...
    茶點故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡遭顶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出泪蔫,到底是詐尸還是另有隱情棒旗,我是刑警寧澤,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布撩荣,位于F島的核電站铣揉,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏婿滓。R本人自食惡果不足惜老速,卻給世界環(huán)境...
    茶點故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望凸主。 院中可真熱鬧橘券,春花似錦、人聲如沸卿吐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嗡官。三九已至箭窜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間衍腥,已是汗流浹背磺樱。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工纳猫, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人竹捉。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓芜辕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親块差。 傳聞我的和親對象是個殘疾皇子侵续,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,500評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學(xué)習(xí)記錄文檔,今天18年5月份再次想寫文章憨闰,發(fā)現(xiàn)簡書還為我保存起的...
    Jenaral閱讀 2,767評論 2 9
  • 當(dāng)你最需要幫助的時候状蜗,請先去幫助有需要的人;當(dāng)你最需要安慰的時候鹉动,請先去安慰傷心的人轧坎;當(dāng)你最需要祝福的時候,請先去...
    王慧聰閱讀 1,172評論 2 4
  • 明天是重陽節(jié)训裆,蘇菲昨天就看了日歷眶根,記著日子呢! 下班時回到家边琉,爸爸告訴她属百,外婆在家一直念叨著,怎么今天重陽節(jié)沒有人...
    飛呀飛me閱讀 311評論 0 2
  • “我要去北京变姨!”老人垂著頭族扰,固執(zhí)地堅持著。 “不是不讓您去定欧,”老人的女兒在一邊苦口婆心地勸渔呵,“現(xiàn)在天越來越冷了每窖,您...
    夢藤閱讀 327評論 0 0
  • 【家庭教育愛分享】 當(dāng)我們從小就沒有被父母耐心對待十兢,投射了太多的焦慮黔牵,就容易對自己的孩子沒有耐心仍稀,把這種焦慮不安和...
    上善若水4閱讀 332評論 3 2