TypeScript interface

typescript之旅

1.TypeScript-Basic
2.TypeScript interface
3.Typescript-module(1)
4.TypeScript Modules(2)
5.Typescript tsconfig
6.TypeScript Functions
7.Typescript Classjavascript

Interfaces

今天來講說接口,首先說明若是你是java程序員,請必定忘記interface,此處的接口和彼處接口徹底不是一個思想。java

首先來一個最簡單的接口
字面量接口git

不使用interface關鍵字就定義了一個接口程序員

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

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

上面沒有interface關鍵字,哪一個是接口呢?
{label: string}
你說這個玩意不是變量labelledObj的類型嗎?我知道typescript說白了就是js的類型系統,前面也介紹瞭如:Boolean,Number,String,Array,Enum,Any,Void
其實接口就是定義了一個對象有哪些屬性,而且屬性值是什麼類型typescript

好了,來個高級點的(interface關鍵詞上場)segmentfault

interface LabelledValue {
  label: string;
}

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

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

OK,懂了嗎,自定義類型
啊,太棒了,之後不再用判斷某個屬性是否un數組

可選屬性

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

function createSquare(config: SquareConfig): {color: string; area: number} {
  let newSquare = {color: "white", area: 100};
  if (config.color) {
    newSquare.color = config.color;
  }
  if (config.width) {
    newSquare.area = config.width * config.width;
  }
  return newSquare;
}

let mySquare = createSquare({color: "black"});

好處:ide

  1. 預約義屬性函數

  2. 編譯器能夠捕獲對不存在屬性引用的錯誤this

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

function createSquare(config: SquareConfig): { color: string; area: number } {
  let newSquare = {color: "white", area: 100};
  if (config.color) {
    // Error: Property 'collor' does not exist on type 'SquareConfig'
    newSquare.color = config.collor;  // Type-checker can catch the mistyped name here
  }
  if (config.width) {
    newSquare.area = config.width * config.width;
  }
  return newSquare;
}

let mySquare = createSquare({color: "black"});

對於這個錯誤例子,咱們引出了下一節

額外的屬性檢查

上面的例子也許有人會爭辯(js的忠實用戶者),js對象是靈活的,你如今搞得跟JAVA同樣了!
反對~反對!

是的,typescript對對象字面量會特殊對待(即通過額外屬性檢查),當將他們賦值給變量或做爲函數參數時。
所以你會獲得一個錯誤

// error: 'colour' not expected in type 'SquareConfig'    
let mySquare = createSquare({ colour: "red", width: 100 });

解決辦法
1.類型斷言法(相似於c語言的強制類型轉換,告訴編譯器,我就要轉,別給我報錯啊!)

let mySquare = createSquare({ colour: "red", width: 100 } as SquareConfig);

2.鑽空子法(咱們瞭解編譯器的檢查方式了,我繞過去就好了)

let squareOptions = { colour: "red", width: 100 };
let mySquare = createSquare(squareOptions);

函數類型

首先咱們要確定interface使咱們定義了各類對象外形。
如今咱們把string,number,boolean,object類型都定義了,完工了!
且慢,等等~對於其餘語言是夠了,但js~~~
你想,js的函數是一等公民,你能忘了它~

噹噹噹當,來了!

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

demo:

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

好處:
1.檢查參數類型
2.返回值類型檢查,上例,若是你返回字符串或數字,就報錯了

數組類型

數組能夠想象成一種特殊函數,只有一個參數(index)的函數

interface StringArray {
  [index: number]: string;
}

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

OK,沒有問題嗎?index只能是number類型嗎?我還知道一種叫關聯數組的玩意(index是string)

咱們常常這樣用obj.property和obj["property"]

  1. 目前支持兩種index類型:number,string

  2. 能夠同時使用兩種索引類型

  3. 限制:數字索引返回值的類型必須是字符串索引返回值的類型的子類型

demo

interface NumberDictionary {
  [index: string]: number;
  length: number;    // 能夠,length是number類型
  name: string       // 錯誤,`name`的類型不是索引類型的子類型
}

類類型(肩負重任的inteface關鍵字)

  • 與C#或Java裏接口的基本做用同樣,TypeScript也可以用它來明確的強制一個類去符合某種契約。

interface ClockInterface {
    currentTime: Date;
}

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

class Clock implements ClockInterface {
    currentTime: Date;
    setTime(d: Date) {
        this.currentTime = d;
    }
    constructor(h: number, m: number) { }
}
  • 接口描述了類的公共部分,而不是公共和私有兩部分。 它不會幫你檢查類是否具備某些私有成員。

類靜態部分與實例部分的區別

  • 這部分比較冷~

  • 類是具備兩個類型的:靜態部分的類型和實例的類型

  • 構造函數是靜態部分,而一個類去實現一個帶有構造器簽名的接口時會報錯

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

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

那如何才能使用接口對構造器類型檢查呢

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

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

拓展接口

  • 和類同樣,接口也能夠相互擴展。 這讓咱們可以從一個接口裏複製成員到另外一個接口裏,能夠更靈活地將接口分割到可重用的模塊裏

interface Shape {
    color: string;
}

interface Square extends Shape {
    sideLength: number;
}

let square = <Square>{};
square.color = "blue";
square.sideLength = 10;

多繼承

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;

混合類型

  • 仍是JS的特殊語法

function demo(){
    ...
}

demo.attr1 = '1';
demo.fun = function(){
    ...
}

這是什麼狀況,函數類型,對象類型,額,混合類型

interface Counter {
    (start: number): string;
    interval: number;
    reset(): void;
}

function getCounter(): Counter {
    let counter = <Counter>function (start: number) { };
    counter.interval = 123;
    counter.reset = function () { };
    return counter;
}

let c = getCounter();
c(10);
c.reset();
c.interval = 5.0;

接口繼承類

  • 還不是很明白

相關文章
相關標籤/搜索