TypeScript入門學習@郝晨光


前言

現(xiàn)在TypeScript越來越火托呕,咱也趕一下潮流充甚,開始學習一下TypeScript演熟,在學習的同時做筆記記錄鞭执,希望可以共同學習,在未來的程序生涯中可以使用TypeScript來進行開發(fā)芒粹。

TypeScript是什么兄纺?

TypeScript 是 JavaScript 的一個超集,主要提供了類型系統(tǒng)對 ES6 的支持化漆,因為JavaScript是弱類型語言估脆,我們在開發(fā)的時候,很容易會因為數據類型的原因造成一些不明不白的錯誤获三,所以旁蔼,在TypeScript中,對類型的檢測是極為嚴格的疙教。

TypeScript的優(yōu)勢

在這里我借用阮一峰大神的文章來說一下TypeScript的優(yōu)勢棺聊。

  1. TypeScript 增加了代碼的可讀性和可維護性;

    • 類型系統(tǒng)實際上是最好的文檔贞谓,大部分的函數看看類型的定義就可以知道如何使用了
    • 可以在編譯階段就發(fā)現(xiàn)大部分錯誤限佩,這總比在運行時候出錯好
    • 增強了編輯器和 IDE 的功能,包括代碼補全裸弦、接口提示祟同、跳轉到定義、重構等
  2. TypeScript 非常包容理疙;

    • TypeScript 是 JavaScript 的超集晕城,.js 文件可以直接重命名為 .ts 即可
    • 即使不顯式的定義類型,也能夠自動做出類型推論
    • 可以定義從簡單到復雜的幾乎一切類型
    • 即使 TypeScript 編譯報錯窖贤,也可以生成 JavaScript 文件
    • 兼容第三方庫砖顷,即使第三方庫不是用 TypeScript 寫的,也可以編寫單獨的類型文件供 TypeScript 讀取
  3. TypeScript 擁有活躍的社區(qū)赃梧;

    • 大部分第三方庫都有提供給 TypeScript 的類型定義文件
    • Google 開發(fā)的 Angular2 就是使用 TypeScript 編寫的
    • TypeScript 擁抱了 ES6 規(guī)范延赌,也支持部分 ESNext 草案的規(guī)范

TypeScript的缺點

  • 無非就是難學了一點沸毁,無所謂啦,反正再難學還是要學的!自己選的路抡句,跪著也要走下去。

寫在前邊

首先一定要從JavaScript的弱類型思想中走出來旧噪,在TypeScript中菌湃,保證在大部分時候都要給數據定義類型。
其次一定要堅持巷折,堅持焕济,堅持。
那就先從基礎開始吧盔几!


安裝使用

  1. 首先全局安裝typescript
    npm install typescript -g
    
  2. 當全局安裝后晴弃,我們就可以在全局下使用tsc指令了
    先通過tsc -v查看一下當前的TypeScript的版本號,順便看一下有沒有安裝成功逊拍。
    tsc -v
    
  3. 接著新建一個文件夾上鞠,新建一個.ts文件,例如: index.ts;
    在使用TypeScript時芯丧,我們使用.ts為后綴的文件芍阎,如果是使用React的時候,我們默認使用.tsx為后綴的文件缨恒。它們分別對應的是.js.jsx文件谴咸。
  4. index.ts文件中轮听,寫入如下代碼
    function sayHello(person: string) {
        return 'Hello' + person;
    }
    let person = [1, 2, 3];
    sayHello(person);
    
  5. 打開命令提示符,通過如下指令編譯TypeScript文件
    tsc index.ts
    
  6. 執(zhí)行會發(fā)現(xiàn)命令提示符報錯index.ts:5:10 - error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'string'岭佳,因為我們給函數的參數定義成為string類型血巍,而我們傳入的是一個數組,所以會報錯珊随。
  7. 但是雖然報錯了述寡,依舊生成了index.js文件,這是因為TypeScript文件就算編譯出錯也依舊會編譯成js文件叶洞,畢竟這點錯誤在咱們的JavaScript里邊不算什么鲫凶。
  8. 接著修改我們的index.ts文件
    function sayHello(person: string) {
        return 'Hello' + person;
    }
    let person: string = '郝晨光';
    sayHello(person);
    
  9. 再次執(zhí)行tsc index.ts指令
  10. 這次命令提示符沒有任何的錯誤信息,并且可以看到生成的index.js文件衩辟。

基本類型

對于基本類型螟炫,直接定義類型即可。定義好就必須指定類型艺晴,不可以變成其它類型不恭。

  1. 定義布爾類型的值
    // 布爾值
    let isDone: boolean = true;
    
  2. 定義數字類型的值
    // 數字
    let count: number = 1;
    
  3. 定義字符串類型的值
    // 字符串
    let str:string = 'typescript';
    
  4. 定義空值
    空值是typescript中新引入的一種基本類型,可以用 void 表示沒有任何返回值的函數财饥。
    function alertName(): void {
        alert('郝晨光加油换吧!')
    }
    
    或者聲明一個空值,但是這樣毫無意義钥星,因為只能被賦值為undefined和null沾瓦。
    let myVoid1: void = undefined;
    let myVoid2: void = null;
    
  5. 定義null和undefined
    // null
    let nullSet: null = null;
    // undefined
    let undeSet: undefined = undefined;
    
    需要注意的是,null和undefined可以被賦予任何類型谦炒,但是void的空值不能被賦予其他類型贯莺。
    let unsetNumber: number = null;
    let unsetString: string = undefined;
    
  6. 任意類型
    我們都非常熟悉JavaScript,在JavaScript中宁改,我們的變量是可以隨時轉換數據類型的缕探,但是在TypeScript中,對于定義好的基本數據類型是不可以的还蹲!那我們如何實現(xiàn)一個不一定是什么數據類型的值呢爹耗?就該使用任意類型了。
    // 任意類型
    // 對于任意類型谜喊,可以在賦值后修改數據類型潭兽。
    let myAny: any = 'string';
    myAny = 123;
    // 變量在聲明的時候沒有指定類型,并且沒有賦值斗遏,自動編譯為 any 類型
    let anyThing;
    anyThing = '未指定類型并且未賦值山卦,自動編譯為 any 類型';
    anyThing = 1234;
    

類型推斷

了解了基本數據類型,接下來就應該先了解一下TypeScript的類型推斷诵次,在TypeScript中账蓉,如果你沒有給(變量/數據)指定一個數據類型枚碗,分為兩種情況,

  1. 一種是定義未賦值铸本,就是我們在上邊的任意類型中提到的肮雨,它會自動聲明成為any類型。
  2. 而如果我們在定義(變量/數據)的時候归敬,給它賦值,但是不給它指定類型的話鄙早,TypeScript就會進行類型推斷汪茧。
    // 但是如果變量在聲明是賦值了,但是沒有指定類型
    // 經過類型推斷限番,它應該是賦值時候的數據類型,即為string舱污。
    let stringThing = '未指定類型,但是賦值為string';
    stringThing = 1234; // 報錯
    
    在上邊的案例中弥虐,在定義stringThing變量定義時扩灯,給它賦值成為string,經過TypeScript的類型推斷后霜瘪,它會被設置成為string數據類型珠插,而當我們給它賦值成為number類型時,TypeScript就會進行報錯颖对。

聯(lián)合類型

我們在實際開發(fā)中經常會遇到這樣的問題捻撑,一個參數,它既有可能是string類型缤底,又有可能是number類型顾患,那這種情況,如果我們用TypeScript應該怎么定義呢个唧?肯定不可能使用any吧江解,那樣的話,我們還可以設置其他類型的值徙歼。所以犁河,就出現(xiàn)了聯(lián)合類型。

// 聯(lián)合類型(多個類型)
let numString: string | number = '一開始是string';
numString = 123456789; // 可以被賦值為number類型
numString = true; // 報錯魄梯,不可以是boolean類型呼股。

但是,針對聯(lián)合類型画恰,只能使用它們之間公共的方法彭谁,不能使用其中一個特有的方法。例如:

// 由于number是沒有l(wèi)ength屬性的允扇,所以會報錯
function getLength(some: string | number): number {
     return some.length;
}

訪問number和string的公共屬性沒有任何問題缠局,不會報錯则奥。

function getString(some: string | number): string {
    return some.toString();
}

聯(lián)合類型會在被賦值的時候推斷出一個類型,并監(jiān)聽除當前數據類型以外的錯誤狭园。

let myName: string | number;
myName = '郝晨光';
// 此時是字符串類型读处,所以調用length屬性沒有任何問題
console.log(myName.length); // 3
myName = 123;
// 此時是number類型,沒有l(wèi)enght屬性唱矛,所以會報錯
console.log(myName); // error TS2339: Property 'length' does not exist on type 'number'.

對象的類型

在ts中罚舱,通過接口(interface)來定義對象的類型;

  1. 接口定義了對象的值的類型绎谦,并且定義了對象的參數管闷,多一個參數少一個參數都不可以。

    interface Person {
        name: string,
        age: number,
        sex: string
    }
    
    let person: Person = {
        name: '郝晨光',
        age: 24,
        sex: '男'
    };
    
  2. 當我們的對象有一些屬性不是必須的時候窃肠,可以通過?來定義包个,?表示屬性是可選的。

    interface People {
        name: string,
        age: number,
        sex?: string
    }
    
    let girl: People = {
        name: 'girl',
        age: 20
    };
    
  3. 當我們的對象有一些未知的屬性時冤留,可以通過[propName]來定義

    interface Student {
        name: string,
        age?: number,
        [propName: string]: string | number
    }
    let student: Student = {
        name: '學生',
        age: 20,
        className: 'A班'
    };
    
    1. 如果設置了propName的話碧囊,可選的值(帶?的值),就必須是propName的指定值的子類型
    2. 例如any纤怒,所有類型都是它的子類型糯而,或者通過聯(lián)合類型來指定
    3. 在上邊的案例中,如果我只給propName指定數據類型為string的話泊窘,TypeScript就會報錯歧蒋,因為age屬性需要的是number類型的值。
  4. 我們還可以給對象設置只讀的屬性州既。

    // 只讀屬性
    // 通過 readonly 屬性來設置屬性是只讀的
    interface Teacher {
        readonly id: number,
        name: string,
        age?: number,
        [propName: string]: any
    }
    let teacher: Teacher = {
        id: 123456,
        name: '郝晨光',
        age: 24,
        className: 'A班'
    };
    console.log(teacher.id);
    teacher.id = 1231546; // 報錯谜洽,因為是只讀的,不能修改
    

數組的類型

在TypeScript中定義數組的方式有很多

  1. 類型 + 方括號
    let arr1: number[] = [1, 2, 3];
    // 如果出現(xiàn)非number的值吴叶,就會報錯
    arr1 =  [1, 2, '1', 3]; // 報錯
    arr1.push(10); // 正常
    arr1.push('10'); // 報錯
    
  2. 數組泛型
    let arr2: Array<number> = [1, 2, 3];
    arr2 = [1, 2, '1', 3]; // 報錯;
    arr2.push(10); //正常
    arr2.push('10'); // 報錯
    
  3. 使用接口interface定義
    interface NumberArray {
        [index: number]: number // 定義數據是number類型
    
        push(number: number): void; // 定義push方法接收number類型的值阐虚,并返回空值
    }
    let arr3: NumberArray = [1, 2, 3];
    arr3 = [1, 2, '1', 3]; // 報錯;
    arr3.push(10); // 正常
    arr3.push('10'); // 報錯
    
  4. 使用any定義數組
    // 數組中允許出現(xiàn)任意類型的值
    let arr4: any[] = [1, '2', new Date(), 3];
    
  5. 類數組
    類數組不能通過數組的方式定義,每一個類數組都有它對應的內置對象
    arguments ==> IArguments
    NodeList ==> NodeList
    HTMLCollection ==> HTMLCollection
    ···
    

函數的類型

在JavaScript中蚌卤,定義函數有兩種方式实束,一種是函數聲明式,另一種是函數表達式逊彭。
在函數定義之后咸灿,輸入多余的(或者少于要求的)參數,是不被允許的侮叮。

  1. 函數聲明式
    function fn(x: number, y: number): number {
        return x + y;
    }
    
  2. 函數表達式
    注意:這樣聲明對于左邊的變量來說避矢,并沒有任何數據指定,雖然不會報錯,但是是不嚴謹的
    let fn2 = function(x: number, y: number): number {
        return x + y;
    };
    
    所以我們應該這樣定義审胸。
    let fn3: (x: number, y: number) => number = function(x: number, y: number): number {
        return x + y;
    };
    
    需要注意的是TypeScript中亥宿,用在此處的 => 與 ES6中的箭頭函數是沒有任何關系的,此處只是為了指定返回值的數據類型砂沛。
  3. 使用接口interface定義函數
    interface Fun {
        (x: number, y: number): number
    }
    // 此時可以不指定右邊的函數的返回值的類型烫扼,因為在接口中定義了
    let fn4: Fun = function(x: number, y: number) {
        return x + y;
    };
    
  4. 可選參數
    function fn5(firstName: string, lastName?: string): string {
        return firstName + ' ' + lastName;
    }
    
    需要注意的是,可選參數必須出現(xiàn)在最后碍庵,不能在可選參數之后又出現(xiàn)必須參數映企。
    下面的案例會報錯!
    function fn6(x?: number,y: number): number {
        return x + y;
    }
    
    函數出現(xiàn)多個可選參數
    // 出現(xiàn)多個可選參數
    function fn7(x: number,y?: number, z?: number): number {
        return x + y + z;
    }
    
  5. 參數默認值
    當定義了默認值時静浴,可選參數將不會在受限制堰氓,可以出現(xiàn)在必須參數前邊,調用時直接傳入null或者undefined即可马绝。
    function fn8(x: number = 5,y: number):number {
        return x + y;
    }
    fn8(null,10); // 15
    fn8(10, 20); // 30
    
  6. 剩余參數
    在ES6中豆赏,可以通過擴展運算符來接收剩余的參數挣菲,剩余參數其實就是一個數組富稻,所以可以通過any[]或者Array<any>等等方式定義類型。
    function fn9(arr: any[], ...args: any[]): Array<any> {
        args.forEach(item => {
            arr.push(item);
        });
        return arr;
    }
    
  7. 函數重載
    重載就是指函數在接收不同類型的參數或者不同數量的參數時白胀,做出不同的處理椭赋,返回不同的結果。
    function reverse(x: number): number;
    function reverse(x: string): string;
    function reverse(x: number | string): number | string {
        if(typeof x === 'number') {
            return Number(x.toString().split('').reverse().join());
        }else if(x === 'string'){
            return x.split('').reverse().join('');
        }
    }
    reverse(123456);
    reverse('123456');
    

本文參考:TypeScript入門教程 - 阮一峰

如果本文對您有幫助或杠,可以看看本人的其他文章:
簡單實現(xiàn)Vue響應式原理@郝晨光
前端常見面試題(十六)@郝晨光
前端常見面試題(十五)@郝晨光

結言
感謝您的查閱哪怔,本文由郝晨光整理并總結,代碼冗余或者有錯誤的地方望不吝賜教向抢;菜鳥一枚认境,請多關照
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市挟鸠,隨后出現(xiàn)的幾起案子叉信,更是在濱河造成了極大的恐慌,老刑警劉巖艘希,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件硼身,死亡現(xiàn)場離奇詭異,居然都是意外死亡覆享,警方通過查閱死者的電腦和手機佳遂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來撒顿,“玉大人丑罪,你說我怎么就攤上這事。” “怎么了巍糯?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵啸驯,是天一觀的道長。 經常有香客問我祟峦,道長罚斗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任宅楞,我火速辦了婚禮针姿,結果婚禮上,老公的妹妹穿的比我還像新娘厌衙。我一直安慰自己距淫,他們只是感情好,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布婶希。 她就那樣靜靜地躺著榕暇,像睡著了一般。 火紅的嫁衣襯著肌膚如雪喻杈。 梳的紋絲不亂的頭發(fā)上彤枢,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天,我揣著相機與錄音筒饰,去河邊找鬼缴啡。 笑死,一個胖子當著我的面吹牛瓷们,可吹牛的內容都是我干的业栅。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼谬晕,長吁一口氣:“原來是場噩夢啊……” “哼碘裕!你這毒婦竟也來了?” 一聲冷哼從身側響起攒钳,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤帮孔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后夕玩,有當地人在樹林里發(fā)現(xiàn)了一具尸體你弦,經...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年燎孟,在試婚紗的時候發(fā)現(xiàn)自己被綠了禽作。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡揩页,死狀恐怖旷偿,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤萍程,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布幢妄,位于F島的核電站,受9級特大地震影響茫负,放射性物質發(fā)生泄漏蕉鸳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一忍法、第九天 我趴在偏房一處隱蔽的房頂上張望潮尝。 院中可真熱鬧,春花似錦饿序、人聲如沸勉失。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乱凿。三九已至,卻和暖如春咽弦,著一層夾襖步出監(jiān)牢的瞬間徒蟆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工离唬, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留后专,地道東北人划鸽。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓输莺,卻偏偏與公主長得像,于是被迫代替她去往敵國和親裸诽。 傳聞我的和親對象是個殘疾皇子嫂用,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內容