TypeScript特性及實踐

本文面向讀者:對ES6知識有一定掌握的,剛開始使用或準(zhǔn)備使用TypeScript的前端同學(xué),對TypeScript感興趣的,以及就是來看看的同學(xué)。(為什么呢!?(?_?;? 因為我使用ts還沒有很長時間,主要是也寫不深 :-D,這篇文章也主要是自己對TypeScript學(xué)習(xí)的一個總結(jié)記錄,方便以后的學(xué)習(xí)回顧,這里我就先介紹一些個人覺得比較實用的ts特性,及相關(guān)的使用)

TypeScript是什么

TypeScript(簡稱ts)是一種由微軟開發(fā)的自由和開源的編程語言。它是 Javascript 的一個超集,擴展了JavaScript的語法. 其本質(zhì)上是向Javascript語言添加了可選的靜態(tài)類型和基于類的面向?qū)ο缶幊獭?br> JavaScript和TypeScript的關(guān)系大家看下面圖片就清楚了:

image

在使用TypeScript之前推薦大家一個比較好用的編輯器Visual Studio Code , 它對ts最友好, 它的代碼提示、片段及調(diào)試功能也非常棒!

TypeScript特性

下面介紹一些ts的特性和相關(guān)的使用。

接口

使用 interface 關(guān)鍵字來定義接口;TypeScript的核心原則之一是對值所具有的結(jié)構(gòu)進行類型檢查。它的作用就是為這些類型命名和為你的代碼或第三方代碼定義契約。(RD們對接口這個詞應(yīng)該很熟悉,現(xiàn)在前端也有了哦,RD們在寫前端的時候用ts會更好理解)
先來個栗子:

interface Person{
    name : string,
    address : string
}
function info(person:Person){
    console.log(person.name+"--"+person.address);
}
let tom = {name:"Tom",age:30,address:"上海"};
info(tom);//輸出 Tom--上海

上例中:

  • info方法限定為接受一個Person類型的參數(shù)
  • 傳入的對象,只要形式上滿足接口要求即可,即:必須含有name(string) 及 address(string)
  • TypeScript并不會檢查屬性順序,只需要有對應(yīng)的屬性存在即可(如果tom對象不含有address或name屬性則會報錯)

上面的例子是一個屬性類型接口, 此外, 可以在屬性名后加 '? '來設(shè)定可選屬性, 在屬性名前用 readonly 來指定只讀屬性。
有個特殊的情況, 當(dāng)你添加了任意數(shù)量的其它額外屬性時,如果按上面這樣寫ts在編譯時類型檢查則會報錯,最佳的方式是能夠添加一個 字符串索引簽名,如下:

interface Person {
            name?: string;
   readonly adress: string;
    [propName: string]: any;
}

接口除了上面講的屬性類型接口,還有函數(shù)類型接口, 可索引類型接口, 類類型接口等。

  • 函數(shù)類型接口:
    可以理解為是定義函數(shù)參數(shù)和返回值類型的接口;
  • 可索引類型接口:
    用來描述可以通過索引得到的類型, 如Array, Object;
  • 類類型接口:
    用來規(guī)范類的內(nèi)容,也就是定義類的屬性和方法類型的接口,需要通過 implements 來實現(xiàn)類接口, 這個interface可以看做是一個抽象類,將一些行為進行抽象,而具體如何行動需要由類去實現(xiàn)。
  • 繼承接口:
    一個接口可以繼承多個接口, 通過接口繼承,可以方便的實現(xiàn)接口復(fù)用, 通過大家熟悉的extends來實現(xiàn)繼承;

命名空間

ts為了與 ECMAScript 2015里的術(shù)語保持一致, “內(nèi)部模塊”現(xiàn)在稱做“命名空間(namespace)”。 “外部模塊”現(xiàn)在則簡稱為“模塊(module)”。
使用namespace關(guān)鍵字 +名稱, 來定義命名空間;
看個栗子理解下:

 namespace Validation {
    export interface Person    {
         name: string
    }
    const  ac= "abc";
    export  function a(){
        console.log("This is a namespace");
    }
}

如上面例子, 把定義好的接口,方法都放到一個叫做Validation的命名空間里, 這樣可以與外部命名空間隔離開,避免了與外部空間的相互影響。如果我們想讓他們在命名空間之外也是可訪問的,需要使用 export。

  • 在某些情況下,我們需要在不同的文件里使用同一個命名空間, 并且在使用的時候就如同它們在一個文件中定義的一樣, 也就是多文件中的命名空間。這里需要用到三斜線指令, 它用于聲明文件間的依賴。也就是告訴編譯器在編譯過程中要引入的額外的文件。如下:
  /// <reference path="..." />
  • 在使用其它的JavaScript庫, 為了讓TypeScript編譯器識別它的類型,我們使用外部命名空間聲明, 在namespace前加declare關(guān)鍵字。

TypeScript在Vue中的實踐

上面介紹了ts中的一些特性,相信大家對ts也已經(jīng)有一定的了解了, 那么我們在實際開發(fā)中如何將ts有效的用到我們的項目中呢?下面來看看如何在vue中使用ts。

項目配置

TypeScript文件是以ts為后綴名的,所以我們需要在webpack中配置ts的加載器,如下:

npm i ts-loader --save-dev

webpack中配置:

{
   entry: {
         app: './src/main.ts'
    },
  resolve: {
    extensions: ['.ts', '.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    }
  },
 module: {
    rules: [
       {
        test: /\.ts$/,
        loader: 'ts-loader',
        options: {
          appendTsSuffixTo: [/\.vue$/],
        }
      },
    ],
  }
}

由于ts有自己的編譯器,所以我們需要在根目錄下新建 tsconfig.json 文件,根據(jù)項目對ts編譯器進行配置。如下:

{
  "compilerOptions": {
    "target": "es5",
    "strict": true,
    "module": "es2015",
    "moduleResolution": "node"
  }
}

上面是一個簡單的配置項,根據(jù)項目的需要我們可以添加其他相關(guān)選項,具體配置請查看官方文檔
由于 TypeScript 默認(rèn)并不支持 *.vue 后綴的文件,所以在 vue 項目中引入的時候需要創(chuàng)建一個 vue-shims.d.ts 文件,放在項目對應(yīng)使用目錄下,例如 src/vue-shims.d.ts

declare module "*.vue" {
  import Vue from "vue";
  export default Vue;
}

這個文件的作用就是告訴 TypeScript *.vue 后綴的文件可以交給 vue 模塊來處理。
在代碼中導(dǎo)入 *.vue 文件的時候,需要寫上 .vue 后綴。這是因為 TypeScript 默認(rèn)只識別 *.ts 文件,不識別 *.vue 文件:

import Component from 'components/index.vue'

需要注意的是在vue文件的script標(biāo)簽里需要添加lang='ts'
至此,這個項目就差不多配置好了,我們就可以在項目里使用ts的語法了。

vue-class-component

vue英文官網(wǎng)推薦了一個叫vue-class-component的包, 它對 Vue 組件進行了一層封裝,讓 Vue 的組件語法在結(jié)合了 TypeScript 語法,我們可以以class的模式寫vue組件。這帶來了很多便利:

  • methods,鉤子都可以直接寫作class的方法
  • computed屬性可以直接通過get來獲得
  • 初始化data可以聲明為class的屬性
  • 其他的都可以放到Component裝飾器里
@Component({
    props: {
        firstName: String,
        lastName: String
    },
    components: {
        'component-a': ComponentA
    }
})
export default class App extends Vue {
    firstName: string;
    lastName: string;
    //初始data
    msg :number = 123;
    //computed
    get fullName ():string {
        return this.firstName + this.lastName;
    }
    //methods
    hello () :void {
        console.log(`Hello ${this.fullName}`);
    }
}

上面就是一個Vue與TypeScript結(jié)合的例子。在Vue官網(wǎng)中也有說明,在 Vue 2.5.0 中,大大改進了類型聲明以更好地使用默認(rèn)的基于對象的 API,更好的TypeScript集成。以上內(nèi)容如有不恰當(dāng)?shù)牡胤剑瑲g迎給予指教!本文中介紹的只是關(guān)于TypeScript的一些內(nèi)容,如果對TypeScript感興趣的同學(xué)可以更深入的研究,歡迎一起來探討!

參考資料:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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