天天看點

初學TypeScript之基本資料類型

TypeScript入門(1)

筆者是換了個工作這個公司使用的是react+typescript技術棧,筆者之前隻是聽過typescript,但是并沒有去了解過,結果就導緻了到公司有一點點崩潰。。可是後來經過了一個禮拜的學習感覺對typescript有了個初步的了解,後來又繼續深入了解,現在突然想到應該還有很多朋友或許和筆者當時一樣處于一種尴尬之地,是以筆者特意來部落格寫總結,幫助其他的朋友。

首先了解typescript是幹什麼的,有什麼用。

typescript是javascript的超集,筆者認為就是限制javascript的,由于javascript是弱類型語言,是以很容易出一些未知的問題,比如說本來想要得到的資料是數組,可是最後卻得到了一個對象,那麼在這種時候你的代碼是肯定有問題的。是以為了避免這樣的情況發生,nodeJS之父就發明了typescript這個語言,用來限制資料類型的一種語言。這樣就可以減少我們之前提過的想要的結果資料類型與真實接收到的資料類型不一緻這個問題就解決了。大大減少了開發過程中的這類問題的出錯率。當然代價就是需要學習這個語言。當然,如果你的js基礎很好的話再加上了解過後端語言,那麼typescript對你來說就特别特别輕松。

使用TypeScript

不管你想在什麼項目當中用到它,你都需要全局安裝typescript

npm install -g typescript
           

TypeScript的資料類型

  1. boolean(布爾值)
  2. number(數字)
  3. string(字元串)
  4. array(數組)
  5. object(對象)
  6. null和undefined(空的和未定義的)
  7. tuple(元祖)
  8. enum(枚舉)
  9. any(任何)
  10. void(空的)
  11. never(永不存在的)
  12. 亦或者是類型斷言,在後面會詳細介紹。

前六個是和JavaScript一樣的。可以轉移至JavaScript資料類型詳細介紹觀看。

元祖類型:

元祖類型允許表示一個已知元素數量和類型的數組,各元素的類型不必相同。比如,你可以定義一對值分别為string和number類型的元祖。

let x: [string, number];
x = ['hello',10];  //OK
x = [10,'hello'];  //報錯
           

當通路一個已知索引的元素,會得到正确的類型:

console.log(x[0].substr(1));    //OK
console.log(x[1].substr(1));	//error,'number' does not have 'substr'
           

當通路一個越界的元素,會使用聯合類型替代:

x[3] = 'world';  //這是可以的,字元串可以指派給(string | number)類型
console.log(x[5].toString());	//OK,‘string’和‘number’都有toString方法
x[6] = true;	//Error,布爾不是(string | number)類型
           

聯合類型是進階主題,我們會在以後的章節裡讨論它。

枚舉類型:

enum類型是對JavaScript标準資料類型的一個補充。像C#等其他語言一樣,使用枚舉類型可以為一組數值賦予友好的名字。

enum Color {Red, Green, Blue}
let c: Color = Color.Green;
           

或者全部采用手動指派:

enum Color {Red = 1, Green = 2, Blue = 4}
let c: Color = Color.Green;
           

枚舉類型提供的一個便利是你可以由枚舉的值得到它的名字。例如,我們知道數值為2,但是不确定它映射到Color裡的哪個名字,我們可以查找相應的名字:

enum Color {Red = 1, Green, Blue}
let colorName: string = Color[2];
console.log(colorName);  //顯示“Green”,因為上面代碼裡它的值是2。預設情況下值遞增1,也可手動指派
           

枚舉常用于定義一個變量可能的值為哪些。

Any類型:

有時候,我們會想要為那些在程式設計階段還不清楚類型的變量指定一個類型。 這些值可能來自于動态的内容,比如來自使用者輸入或第三方代碼庫。 這種情況下,我們不希望類型檢查器對這些值進行檢查而是直接讓它們通過編譯階段的檢查。 那麼我們可以使用 any類型來标記這些變量:

let notSure: any = 4;
notSure = 'hello world';
notSure = false;
           

這樣就可以将notSure定義為任意類型的資料了。

在對現有代碼進行改寫的時候,any類型是十分有用的,它允許你在編譯時可選擇地包含或移除類型檢查。 你可能認為 Object有相似的作用,就像它在其它語言中那樣。 但是 Object類型的變量隻是允許你給它賦任意值 - 但是卻不能夠在它上面調用任意的方法,即便它真的有這些方法:

let notSure: any = 4;
notSure.ifItExists();	//OK,ifItExists might exist at runtime
notSure.toFixed();	//OK, toFixed exists (but the compiler doesn't check)

let prettySure: Object = 4;
PrettySure.toFixed();	//Error:Property 'toFixed' doesn't exist on type 'Object'.
           

當你隻知道一部分資料的類型時,any類型也是很有用的。比如,你有一個數組,它包含了不同類型的資料:

let list:any[] = [1,false,"hello"];
//也可以寫成
let list:Array<any> = [1,false,'hello'];

list[1] = 100;
           

Void類型:

某種程度上來說,void類型像是與any類型相反,他表示沒有任何類型。當一個函數沒有傳回值時,你通常會見到其傳回值類型是void:

function warnUser(): void {
	console.log('this is my warning message')
}
           

聲名一個void類型的變量沒有什麼大用,因為你隻能賦予undefined和null:

let unusable: void = undefined;
           

Never類型:

never類型表示的是那些永不存在的值的類型。例如,never類型是那些總是會抛出異常或根本就不會有傳回值函數表達式或箭頭函數表達式的傳回值類型;變量也可以是never類型,當他們被永不為真的類型保護所限制時。

never類型是任何類型的子類型,也可以指派給任何類型;然而,沒有類型是never的子類型或可以指派給never類型(除了never本身之外)。即使any也不可以指派給never。

下面是一些傳回never類型的函數:

//傳回never的函數必須存在無法達到的終點
function error(message: string): never {
	throw new Error(message);
}

//推斷的傳回值類型為never
function fail() {
	return error('something failed');
}

//傳回never的函數必須存在無法達到的終點
function infiniteLoop(): never {
	while (true) {

	}
}
           

類型斷言:

有時候你會遇到這樣的情況,你會比TypeScript更了解某個值的詳細資訊。通常這會發生在你清楚的知道一個實體具有比它現有類型更确切的類型。

通過類型斷言這種方式可以告訴編輯器,“相信我,我知道自己在幹什麼”。類型斷言好比其他語言裡的類型轉換,但是不進行特殊的資料檢查和結構。它沒有運作時的影響,隻是在編譯階段起作用。TypeScript會假設你,程式員,已經進行了必須的檢查。

類型斷言有倆種形式。其一是"尖角号"的寫法:

let someValue: any = 'this is a string';

let strLength: number = (<string>someValue).length;
           

另一個為as文法:

let someValue: any = 'this is a message';

let strLength: number = (someValue as string).length;
           

倆種形式是等價的。至于使用哪個大多數情況下是憑個人喜好;筆者由于最開始的項目就是react結合typescript的項目,在JSX文法裡隻有as文法斷言是被允許的,是以筆者是比較習慣寫as文法的。

  1. 定義變量的時候
let a: string = 'hello world';
           
  1. 定義函數參數的時候
function a(b: number) {

}
           
  1. 定義函數傳回值的時候
function a(): boolean {
	return true;
}