TypeScript學(xué)習(xí)——基礎(chǔ)類型與接口

基礎(chǔ)類型

TypeScript支持與JavaScript幾乎相同的數(shù)據(jù)類型,包括最簡單的數(shù)據(jù)單元:數(shù)字,字符串逞频,結(jié)構(gòu)體,布爾值等基协,定義方式如下:

// 布爾值
let isDone: boolean = false;

// 數(shù)字澜驮,支持十進(jìn)制、十六進(jìn)制卦绣、二進(jìn)制和八進(jìn)制
let decLiteral: number = 6;
let hexLiteral: number = 0xf00d;
let binaryLiteral: number = 0b1010;
let octalLiteral: number = 0o744;

// 字符串
let name: string = "bob";

// 數(shù)組
let list: number[] = [1, 2, 3];  // 可以在元素類型后面接上 [],表示由此類型元素組成的一個數(shù)組
let list: Array<number> = [1, 2, 3];  // 或者使用數(shù)組泛型

// 元組
// 元組類型允許表示一個已知元素數(shù)量和類型的數(shù)組,各元素的類型不必相同樟凄。
let x: [string, number];

// 枚舉
// enum類型是對JavaScript標(biāo)準(zhǔn)數(shù)據(jù)類型的一個補充。 像C#等其它語言一樣叔壤,使用枚舉類型可以為一組數(shù)值賦予友好的名字。
// 默認(rèn)情況下妄田,從0開始為元素編號。 你也可以手動的指定成員的數(shù)值。
enum Color {Red, Green, Blue}
let c: Color = Color.Green;

除了這些最簡單的數(shù)據(jù)單元外珊泳,TypeScript的基礎(chǔ)類型還包括Any、Void、Object等:

  • Any: 有時候,我們會想要為那些在編程階段還不清楚類型的變量指定一個類型愉镰。 這些值可能來自于動態(tài)的內(nèi)容,比如來自用戶輸入或第三方代碼庫碗降。 這種情況下动看,我們不希望類型檢查器對這些值進(jìn)行檢查而是直接讓它們通過編譯階段的檢查。 那么我們可以使用 any類型來標(biāo)記這些變量:
let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean
  • Void: 某種程度上來說,void類型像是與any類型相反奶甘,它表示沒有任何類型吭产。 當(dāng)一個函數(shù)沒有返回值時臣淤,你通常會見到其返回值類型是 void:
function warnUser(): void {
    console.log("This is my warning message");
}
  • Null 和 Undefined: TypeScript里邑蒋,undefined和null兩者各自有自己的類型分別叫做undefined和null。 和 void相似逮京,它們的本身的類型用處不是很大:
let u: undefined = undefined;
let n: null = null;
  • Never: never類型表示的是那些永不存在的值的類型。 例如策严, never類型是那些總是會拋出異常或根本就不會有返回值的函數(shù)表達(dá)式或箭頭函數(shù)表達(dá)式的返回值類型倔韭; 變量也可能是 never類型,當(dāng)它們被永不為真的類型保護(hù)所約束時份名。
    never類型是任何類型的子類型,也可以賦值給任何類型辰如;然而凯正,沒有類型是never的子類型或可以賦值給never類型(除了never本身之外)。 即使 any也不可以賦值給never梧疲。
// 返回never的函數(shù)必須存在無法達(dá)到的終點
function error(message: string): never {
    throw new Error(message);
}

// 推斷的返回值類型為never
function fail() {
    return error("Something failed");
}

// 返回never的函數(shù)必須存在無法達(dá)到的終點
function infiniteLoop(): never {
    while (true) {
    }
}
  • Object: object表示非原始類型,也就是除number米者,string,boolean败明,symbol妻顶,null或undefined之外的類型讳嘱。
    使用object類型,就可以更好的表示像Object.create這樣的API嬉挡。例如:
declare function create(o: object | null): void;

create({ prop: 0 }); // OK
create(null); // OK

create(42); // Error
  • 類型斷言: 類型斷言好比其它語言里的類型轉(zhuǎn)換,但是不進(jìn)行特殊的數(shù)據(jù)檢查和解構(gòu)基括。 它沒有運行時的影響匠璧,只是在編譯階段起作用。 TypeScript會假設(shè)你裁厅,程序員,已經(jīng)進(jìn)行了必須的檢查。
// 尖括號寫法
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;

// as寫法茬故,jsx中只能用這個
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;

接口

在TypeScript中,接口存在的意義就是對值的類型進(jìn)行命名和為你的代碼或第三方代碼定義契約钾腺。

基礎(chǔ)用法
interface LabelledValue {
  label: string;
}

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

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

和其它語言不同的是,只要傳入的對象滿足接口定義的必要條件,那么就是被允許的厢破。

可選屬性
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"});

若要定義可選屬性,可在可選屬性名字定義的后面加一個?符號加勤。
可選屬性可以對可能存在的屬性進(jìn)行預(yù)定義未檩,并且可以捕獲引用了不存在的屬性時的錯誤冤狡。

只讀屬性
interface Point {
    readonly x: number;
    readonly y: number;
}
let p1: Point = { x: 10, y: 20 };
p1.x = 5; // error!

在屬性名前用readonly來指定只讀屬性悲雳。

let a: number[] = [1, 2, 3, 4];
let ro: ReadonlyArray<number> = a;
ro[0] = 12; // error!
ro.push(5); // error!
ro.length = 100; // error!
a = ro; // error!

TypeScript具有ReadonlyArray<T>類型,它與Array<T>相似晴楔,只是把所有可變方法都去掉了。

額外的屬性檢查
interface SquareConfig {
    color?: string;
    width?: number;
}

function createSquare(config: SquareConfig): { color: string; area: number } {
    // ...
}

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

上面的代碼會報錯,原因是TypeScript會認(rèn)為這段代碼可能存在bug导匣。對象字面量會被特殊對待而且會經(jīng)過額外屬性檢查,當(dāng)將它們賦值給變量或作為參數(shù)傳遞的時候缓待。如果一個對象字面量存在任何“目標(biāo)類型”不包含的屬性時旋炒,就會報錯瘫镇。
繞開這些檢查的方式有以下幾種:

// 使用類型斷言
let mySquare = createSquare({ width: 100, opacity: 0.5 } as SquareConfig);

// 更改接口的定義谚咬,使得它可以接受任意其它的屬性
interface SquareConfig {
    color?: string;
    width?: number;
    [propName: string]: any;
}

// 將對象賦值給一個變量
let squareOptions = { colour: "red", width: 100 };
let mySquare = createSquare(squareOptions);
函數(shù)類型
interface SearchFunc {
  (source: string, subString: string): boolean;
}

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

接口也可以描述函數(shù)類型,如上面代碼所示,它就像是一個只有參數(shù)列表和返回值類型的函數(shù)定義尚辑。參數(shù)列表里的每個參數(shù)都需要名字和類型。

可索引的類型
interface StringArray {
  [index: number]: string;
}

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

let myStr: string = myArray[0];

TypeScript支持兩種索引簽名:字符串和數(shù)字澈蝙。 可以同時使用兩種類型的索引盐杂,但是數(shù)字索引的返回值必須是字符串索引返回值類型的子類型链烈。

類類型
interface ClockInterface {
    currentTime: Date;
    setTime(d: Date);
}

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

TypeScript中接口同樣可以用來明確的強制一個類去符合某種契約擦秽。

繼承接口
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;

TypeScript中的接口可以相互繼承,并且一個接口可以繼承多個接口

混合類型

一個對象可以同時做為函數(shù)和對象使用触幼,并帶有額外的屬性堂鲤。

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;

在使用JavaScript第三方庫的時候,可能需要像上面那樣去完整地定義類型。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末敏晤,一起剝皮案震驚了整個濱河市嘴脾,隨后出現(xiàn)的幾起案子译打,更是在濱河造成了極大的恐慌乔询,老刑警劉巖竿刁,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件食拜,死亡現(xiàn)場離奇詭異副编,居然都是意外死亡,警方通過查閱死者的電腦和手機惑惶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門带污,熙熙樓的掌柜王于貴愁眉苦臉地迎上來香到,“玉大人报破,你說我怎么就攤上這事充易。” “怎么了盹靴?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長辕狰。 經(jīng)常有香客問我,道長悬钳,這世上最難降的妖魔是什么偶翅? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任聚谁,我火速辦了婚禮,結(jié)果婚禮上媳搪,老公的妹妹穿的比我還像新娘骤宣。我一直安慰自己,他們只是感情好憔披,可當(dāng)我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布芬膝。 她就那樣靜靜地躺著,像睡著了一般筹误。 火紅的嫁衣襯著肌膚如雪癣缅。 梳的紋絲不亂的頭發(fā)上哄酝,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天陶衅,我揣著相機與錄音直晨,去河邊找鬼。 笑死罩句,一個胖子當(dāng)著我的面吹牛儒士,可吹牛的內(nèi)容都是我干的着撩。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼拖叙,長吁一口氣:“原來是場噩夢啊……” “哼薯鳍!你這毒婦竟也來了挨措?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤斩松,失蹤者是張志新(化名)和其女友劉穎惧盹,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體钧椰,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡嫡霞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年秒际,在試婚紗的時候發(fā)現(xiàn)自己被綠了悬赏。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闽颇。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡兵多,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出剩膘,到底是詐尸還是另有隱情盆顾,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布奈懒,位于F島的核電站宪巨,受9級特大地震影響磷杏,放射性物質(zhì)發(fā)生泄漏极祸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一遥金、第九天 我趴在偏房一處隱蔽的房頂上張望汰规。 院中可真熱鬧物邑,春花似錦、人聲如沸色解。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至道批,卻和暖如春入撒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背璃赡。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工献雅, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人侯谁。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓章钾,卻偏偏與公主長得像,于是被迫代替她去往敵國和親嫩痰。 傳聞我的和親對象是個殘疾皇子剿吻,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,762評論 2 345

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