相信你在寫JavaScript代碼的時候也碰到過很頭疼的時刻,比如對象的屬性名或方法名大小寫錯了,或是記不得某個對象有沒有某個屬性,害怕最新的ES標準有的瀏覽器還沒有支持...等等種種問題,那麼你需要使用TypeScript,你會愛上她的(●'◡'●)。 TypeScript是JavaScript的 ...
相信你在寫JavaScript代碼的時候也碰到過很頭疼的時刻,比如對象的屬性名或方法名大小寫錯了,或是記不得某個對象有沒有某個屬性,害怕最新的ES標準有的瀏覽器還沒有支持...等等種種問題,那麼你需要使用TypeScript,你會愛上她的(●'◡'●)。
TypeScript是JavaScript的超級,她是靜態類型檢查的
這就意味著,你的變數、函數參數、返回值等等都是確定類型的,當你試圖使用不相容的類型,那麼你的開發工具會提示你錯誤,並且拒絕給你編譯。
開發工具智能提示
主流的開發工具都支持TypeScript,智能提示會讓你感覺像是在使用Idea來寫Java代碼一樣的享受。
方便的代碼重構
面向對象與介面編程,擁有非常清晰的代碼結構,可讀性大大提高。
容易上手,初次接觸,也能看懂
高度相容原生腳本語法,對語法的破壞性較少,即使沒接觸過的人,也能很快上手,初次閱讀也沒有什麼障礙。
本著解決JavaScript的糟糕之處,這註定是個不平凡的開源項目。
Phaser、Cocos2dx、laybox、白鷺等等游戲引擎都有TS版本。更多的使用TypeScript的開源項目可以參考這裡。
關於開發環境搭建與調試配置可以參考這裡。
下麵正式介紹TypeScript的基礎類型,無論學習一門什麼語言,從基礎類型開始都再合適不過了。
- 先介紹兩個關鍵字let和const
```
//let const
//let 定義的變數有一個新的變數環境
for (let i = 0; i < 10 ; i++) {
setTimeout(function() {console.log(i); }, 100 * i);
}
//const 定義的變數屬於常量,不能更改
const a: number = 19;
//a = 20;//錯誤,不允許改變常量
const alian = {
name: "alian",
age: 35
}
// 錯誤,因為alian是const定義的
// alian = {
// name: "haha",
// age:22
// }
>let定義的變數不會像var定義的變數那樣污染全局環境。
const定義一個對象的時候,可以修改對象的屬性值,但是不能修改對象引用。
* **布爾類型**
// 布爾類型
let success: boolean = true;
let failed: boolean = false;
>類型名**boolean**定義一個布爾類型,值為*true*或*false*。如果不寫類型名,則會自動推斷出類型。
* **數字類型**
// 數字類型
let dec: number = 9;//10進位
let hex: number = 0xABCD;//16進位
let bin: number = 0b1011;//二進位
let octal: number = 0o123;//八進位
>關鍵字**number**定義一個數字類型,值可以是二進位(0b開頭)、八進位(0o開頭)、十進位、十六進位(0x開頭)。
* **字元串**
// 字元串
let hello: string = "hello";
let world: string = 'world';
let today: number = 1.26;
let express: string = ${hello} ${world}, today is ${today}
;//模版字元串
>關鍵字**string**定義一個字元串變數。
使用``定義一個多行字元串(可以帶有表達式 **${變數名}**)。
* **數組**
// 數組
let numbers: number[] = [0x1, 0o32, 0b11, 3, 2, 1];
let names: string[] = ['ana', 'hello', ${hello} + ${world}
];
let result: Array
>**類型名稱[]** 定義一個指定類型的數組。
**Array<類型名稱>** 同樣定義一個指定類型的數組。
* **元組 Tuple**
//元組 Tuple
let x: [string, number, boolean];
x = ['name', 35, false];
console.log(x[0].substr(1)); //ame
console.log(x[1].toString()); //35
> **[類型名、類型名...]** 定義一個元組,一個元組裡可以包含幾個不同類型的變數。
* **枚舉**
//枚舉
enum Color {Red = 1, Green, Blue}
let color: Color = Color.Blue;
let color2: string = Color[2];
console.log(color2); //Green
>非常有用的一種類型。關鍵字**enum name{value...}** 定義一個枚舉。預設情況下,從0開始為元素編號,可以手動設置一個數字編號,後面沒有設置編號的會依次往上疊加。
>TypeScript 2.4開始支持枚舉成員變數包含字元串構造器,如***enum Color {Red = 'a', Green = 'b', Blue = 'ccc'}***,只是每個元素的編號都要手動設置,需要註意的是字元串枚舉成員不能被反向映射到枚舉成員的名字。 換句話說,你不能使用 Color["a"] 來得到 "Red" 。。
>有了枚舉就可以把同類型但是互斥的變數定義成一個枚舉,而不用定義成一些變數了(比如描述一個音量開關按鈕的開關狀態等等)。
* **Any**
//Any
let y: any = 4;
y = false;
y = 'type not sure';
//y.name();
console.log((y as string).length); //13
let anyArray: Array
>雖然是強類型的,但是有了**any**就有了自由。一個定義為any類型的變數,在使用的過程中可以改變它的值類型,甚至可以調用它的方法,但是需要小心,如果沒有這個方法,會出異常。
![不存在的方法](//upload-images.jianshu.io/upload_images/9984013-af1fe2aa93c1f1e7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
* **Void**
//Void
function noReturn(): void {
console.log('no return function');
}
let useless: void = null;
useless = undefined;
>某種程度上來說,**void**類型像是與**any**類型相反,它表示沒有任何類型。比如定義一個方法沒有返回值。
聲明一個**void**類型的變數沒有什麼大用,因為你只能為它賦予*undefined*和*null*。
* **Null 和 Undefined**
//Null 和 Undefined
let u: undefined = undefined;
let n: null = null;
let age: number = undefined;
let married: boolean = null;
>和 **void**相似,它們的本身的類型用處不是很大。
預設情況下**null**和**undefined**是所有類型的子類型。 就是說你可以把 **null**和**undefined**賦值給其它類型(比如**number**、**string**等等)的變數。
* **Never**
//Never
function fail(message: string): never {
throw new Error(message);
}
>同樣是一個沒什麼用的類型。**never**類型表示的是那些永不存在的值的類型。 例如, **never**類型是那些總是會拋出異常或根本就不會有返回值的函數表達式或Lambda表達式的返回值類型。
* **類型斷言**
let y: any = 4;
y = false;
y = 'type not sure';
//y.name();
console.log((y as string).length); //13
console.log(
當我確定某個變數是什麼類型的時候可以使用類型斷言,明確告訴編譯器我知道它是什麼類型。類型斷言使用y as string或者兩種方式都行。
九層之台,起於壘土,千里之行,始於足下。有了類型基礎,就可以對TypeScript進行下一步的觀光學習了。