本文面向讀者:對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)系大家看下面圖片就清楚了:
在使用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é)可以更深入的研究,歡迎一起來探討!
參考資料: