TypeScript系列(一):初識(shí)TypeScript

1、初識(shí)TypeScript

image.png

TypeScript 的介紹

TypeScript是一種由微軟開(kāi)發(fā)的開(kāi)源兵志、跨平臺(tái)的編程語(yǔ)言醇蝴。它是JavaScript的超集,最終會(huì)被編譯為JavaScript代碼想罕。
2012年10月悠栓,微軟發(fā)布了首個(gè)公開(kāi)版本的TypeScript霉涨,2013年6月19日,在經(jīng)歷了一個(gè)預(yù)覽版之后微軟正式發(fā)布了正式版TypeScript
TypeScript的作者是安德斯·海爾斯伯格惭适,C#的首席架構(gòu)師笙瑟。它是開(kāi)源和跨平臺(tái)的編程語(yǔ)言。
TypeScript擴(kuò)展了JavaScript的語(yǔ)法癞志,所以任何現(xiàn)有的JavaScript程序可以運(yùn)行在TypeScript環(huán)境中往枷。
TypeScript是為大型應(yīng)用的開(kāi)發(fā)而設(shè)計(jì),并且可以編譯為JavaScript凄杯。

TypeScript 是 JavaScript 的一個(gè)超集错洁,主要提供了類(lèi)型系統(tǒng)對(duì) ES6+ 的支持,它由 Microsoft 開(kāi)發(fā)戒突,代碼開(kāi)源于 GitHub

TypeScript 的特點(diǎn)

TypeScript 主要有 3 大特點(diǎn):

  • 始于JavaScript屯碴,歸于JavaScript

TypeScript 可以編譯出純凈、 簡(jiǎn)潔的 JavaScript 代碼膊存,并且可以運(yùn)行在任何瀏覽器上窿锉、Node.js 環(huán)境中和任何支持 ECMAScript 3(或更高版本)的JavaScript 引擎中。

  • 強(qiáng)大的類(lèi)型系統(tǒng)

類(lèi)型系統(tǒng)允許 JavaScript 開(kāi)發(fā)者在開(kāi)發(fā) JavaScript 應(yīng)用程序時(shí)使用高效的開(kāi)發(fā)工具和常用操作比如靜態(tài)檢查和代碼重構(gòu)膝舅。

  • 先進(jìn)的 JavaScript

TypeScript 提供最新的和不斷發(fā)展的 JavaScript 特性嗡载,包括那些來(lái)自 2015 年的 ECMAScript 和未來(lái)的提案中的特性,比如異步功能和 Decorators仍稀,以幫助建立健壯的組件洼滚。

總結(jié)

TypeScript 在社區(qū)的流行度越來(lái)越高,它非常適用于一些大型項(xiàng)目技潘,也非常適用于一些基礎(chǔ)庫(kù)遥巴,極大地幫助我們提升了開(kāi)發(fā)效率和體驗(yàn)。

2享幽、 安裝 TypeScript

命令行運(yùn)行如下命令铲掐,全局安裝 TypeScript:

npm install -g typescript

安裝完成后,在控制臺(tái)運(yùn)行如下命令值桩,檢查安裝是否成功(3.x):

tsc -V 

3摆霉、第一個(gè) TypeScript 程序

編寫(xiě) TS 程序

src/helloworld.ts

function greeter (person) {
  return 'Hello, ' + person
}

let user = 'Yee'

console.log(greeter(user))

手動(dòng)編譯代碼

我們使用了.ts擴(kuò)展名,但是這段代碼僅僅是 JavaScript 而已奔坟。
在命令行上携栋,運(yùn)行 TypeScript 編譯器:

tsc helloworld.ts

輸出結(jié)果為一個(gè) helloworld.js文件,它包含了和輸入文件中相同的 JavsScript 代碼咳秉。
在命令行上婉支,通過(guò) Node.js 運(yùn)行這段代碼:

node helloworld.js

控制臺(tái)輸出:

Hello, Yee

vscode自動(dòng)編譯

1). 生成配置文件tsconfig.json
    tsc --init
2). 修改tsconfig.json配置
    "outDir": "./js",
    "strict": false,    
3). 啟動(dòng)監(jiān)視任務(wù): 
    終端 -> 運(yùn)行任務(wù) -> 監(jiān)視tsconfig.json

類(lèi)型注解

接下來(lái)讓我們看看 TypeScript 工具帶來(lái)的高級(jí)功能。 給 person函數(shù)的參數(shù)添加 :string 類(lèi)型注解澜建,如下:

function greeter (person: string) {
  return 'Hello, ' + person
}

let user = 'Yee'

console.log(greeter(user))

TypeScript 里的類(lèi)型注解是一種輕量級(jí)的為函數(shù)或變量添加約束的方式向挖。 在這個(gè)例子里蝌以,我們希望 greeter 函數(shù)接收一個(gè)字符串參數(shù)。 然后嘗試把 greeter 的調(diào)用改成傳入一個(gè)數(shù)組:

function greeter (person: string) {
  return 'Hello, ' + person
}

let user = [0, 1, 2]

console.log(greeter(user))

重新編譯何之,你會(huì)看到產(chǎn)生了一個(gè)錯(cuò)誤:

error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'string'.

類(lèi)似地饼灿,嘗試刪除 greeter調(diào)用的所有參數(shù)。 TypeScript 會(huì)告訴你使用了非期望個(gè)數(shù)的參數(shù)調(diào)用了這個(gè)函數(shù)帝美。 在這兩種情況中,TypeScript提供了靜態(tài)的代碼分析晤硕,它可以分析代碼結(jié)構(gòu)和提供的類(lèi)型注解悼潭。

要注意的是盡管有錯(cuò)誤,greeter.js 文件還是被創(chuàng)建了舞箍。 就算你的代碼里有錯(cuò)誤舰褪,你仍然可以使用 TypeScript。但在這種情況下疏橄,TypeScript 會(huì)警告你代碼可能不會(huì)按預(yù)期執(zhí)行占拍。

接口

讓我們繼續(xù)擴(kuò)展這個(gè)示例應(yīng)用。這里我們使用接口來(lái)描述一個(gè)擁有 firstNamelastName 字段的對(duì)象捎迫。 在 TypeScript里晃酒,只在兩個(gè)類(lèi)型內(nèi)部的結(jié)構(gòu)兼容,那么這兩個(gè)類(lèi)型就是兼容的窄绒。 這就允許我們?cè)趯?shí)現(xiàn)接口時(shí)候只要保證包含了接口要求的結(jié)構(gòu)就可以贝次,而不必明確地使用 implements 語(yǔ)句。

interface Person {
  firstName: string
  lastName: string
}

function greeter (person: Person) {
  return 'Hello, ' + person.firstName + ' ' + person.lastName
}

let user = {
  firstName: 'Yee',
  lastName: 'Huang'
}

console.log(greeter(user))

類(lèi)

最后彰导,讓我們使用類(lèi)來(lái)改寫(xiě)這個(gè)例子蛔翅。 TypeScript 支持 JavaScript 的新特性,比如支持基于類(lèi)的面向?qū)ο缶幊獭?/p>

讓我們創(chuàng)建一個(gè) User 類(lèi)位谋,它帶有一個(gè)構(gòu)造函數(shù)和一些公共字段山析。因?yàn)轭?lèi)的字段包含了接口所需要的字段,所以他們能很好的兼容掏父。

還要注意的是笋轨,我在類(lèi)的聲明上會(huì)注明所有的成員變量,這樣比較一目了然赊淑。

class User {
  fullName: string
  firstName: string
  lastName: string

  constructor (firstName: string, lastName: string) {
    this.firstName = firstName
    this.lastName = lastName
    this.fullName = firstName + ' ' + lastName
  }
}

interface Person {
  firstName: string
  lastName: string
}

function greeter (person: Person) {
  return 'Hello, ' + person.firstName + ' ' + person.lastName
}

let user = new User('Yee', 'Huang')

console.log(greeter(user))

重新運(yùn)行 tsc greeter.ts翩腐,你會(huì)看到 TypeScript 里的類(lèi)只是一個(gè)語(yǔ)法糖,本質(zhì)上還是 JavaScript函數(shù)的實(shí)現(xiàn)膏燃。

4茂卦、使用webpack打包TS

下載依賴(lài)

npm install -D typescript
npm install -D webpack webpack-cli
npm install -D webpack-dev-server
npm install -D html-webpack-plugin clean-webpack-plugin
npm install -D ts-loader
npm install -D cross-env

入口JS: src/main.ts

document.write('Hello Webpack TS!')

index頁(yè)面: public/index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>webpack & TS</title>
</head>
<body>
  
</body>
</html>

build/webpack.config.js

const {CleanWebpackPlugin} = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const path = require('path')

const isProd = process.env.NODE_ENV === 'production' // 是否生產(chǎn)環(huán)境

function resolve (dir) {
  return path.resolve(__dirname, '..', dir)
}

module.exports = {
  mode: isProd ? 'production' : 'development',
  entry: {
    app: './src/main.ts'
  },

  output: {
    path: resolve('dist'),
    filename: '[name].[contenthash:8].js'
  },

  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        include: [resolve('src')]
      }
    ]
  },

  plugins: [
    new CleanWebpackPlugin({
    }),

    new HtmlWebpackPlugin({
      template: './public/index.html'
    })
  ],

  resolve: {
    extensions: ['.ts', '.tsx', '.js']
  },

  devtool: isProd ? 'cheap-module-source-map' : 'cheap-module-eval-source-map',

  devServer: {
    host: 'localhost', // 主機(jī)名
    stats: 'errors-only', // 打包日志輸出輸出錯(cuò)誤信息
    port: 8081,
    open: true
  },
}

配置打包命令

"dev": "cross-env NODE_ENV=development webpack-dev-server --config build/webpack.config.js",
"build": "cross-env NODE_ENV=production webpack --config build/webpack.config.js"

運(yùn)行與打包

npm run dev
npm run build

5、其他

聲明文件

當(dāng)使用第三方庫(kù)時(shí)组哩,我們需要引用它的聲明文件等龙,才能獲得對(duì)應(yīng)的代碼補(bǔ)全处渣、接口提示等功能

什么是聲明語(yǔ)句

假如我們想使用第三方庫(kù) jQuery,一種常見(jiàn)的方式是在 html 中通過(guò) <script> 標(biāo)簽引入 jQuery蛛砰,然后就可以使用全局變量 $jQuery 了罐栈。

但是在 ts 中,編譯器并不知道 $jQuery 是什么東西

/* 
當(dāng)使用第三方庫(kù)時(shí)泥畅,我們需要引用它的聲明文件荠诬,才能獲得對(duì)應(yīng)的代碼補(bǔ)全、接口提示等功能位仁。
聲明語(yǔ)句: 如果需要ts對(duì)新的語(yǔ)法進(jìn)行檢查, 需要要加載了對(duì)應(yīng)的類(lèi)型說(shuō)明代碼
  declare var jQuery: (selector: string) => any;
聲明文件: 把聲明語(yǔ)句放到一個(gè)單獨(dú)的文件(jQuery.d.ts)中, ts會(huì)自動(dòng)解析到項(xiàng)目中所有聲明文件
下載聲明文件: npm install @types/jquery --save-dev
*/

jQuery('#foo');
// ERROR: Cannot find name 'jQuery'

這時(shí)柑贞,我們需要使用 declare var 來(lái)定義它的類(lèi)型

declare var jQuery: (selector: string) => any;

jQuery('#foo');

declare var 并沒(méi)有真的定義一個(gè)變量,只是定義了全局變量 jQuery 的類(lèi)型聂抢,僅僅會(huì)用于編譯時(shí)的檢查钧嘶,在編譯結(jié)果中會(huì)被刪除。它編譯結(jié)果是:

jQuery('#foo');

一般聲明文件都會(huì)單獨(dú)寫(xiě)成一個(gè) xxx.d.ts 文件

創(chuàng)建 01_jQuery.d.ts, 將聲明語(yǔ)句定義其中, TS編譯器會(huì)掃描并加載項(xiàng)目中所有的TS聲明文件

declare var jQuery: (selector: string) => any;

很多的第三方庫(kù)都定義了對(duì)應(yīng)的聲明文件庫(kù), 庫(kù)文件名一般為 @types/xxx, 可以在 https://www.npmjs.com/package/package 進(jìn)行搜索

有的第三庫(kù)在下載時(shí)就會(huì)自動(dòng)下載對(duì)應(yīng)的聲明文件庫(kù)(比如:webpack),有的可能需要單獨(dú)下載(比如jQuery/react)

內(nèi)置對(duì)象

JavaScript 中有很多內(nèi)置對(duì)象琳疏,它們可以直接在 TypeScript 中當(dāng)做定義好了的類(lèi)型有决。

內(nèi)置對(duì)象是指根據(jù)標(biāo)準(zhǔn)在全局作用域(Global)上存在的對(duì)象。這里的標(biāo)準(zhǔn)是指 ECMAScript 和其他環(huán)境(比如 DOM)的標(biāo)準(zhǔn)空盼。

1.ECMAScript 的內(nèi)置對(duì)象

Boolean
Number
String
Date
RegExp
Error

/* 1. ECMAScript 的內(nèi)置對(duì)象 */
let b: Boolean = new Boolean(1)
let n: Number = new Number(true)
let s: String = new String('abc')
let d: Date = new Date()
let r: RegExp = /^1/
let e: Error = new Error('error message')
b = true
// let bb: boolean = new Boolean(2)  // error

2.BOM 和 DOM 的內(nèi)置對(duì)象

Window
Document
HTMLElement
DocumentFragment
Event
NodeList

const div: HTMLElement = document.getElementById('test')
const divs: NodeList = document.querySelectorAll('div')
document.addEventListener('click', (event: MouseEvent) => {
  console.dir(event.target)
})
const fragment: DocumentFragment = document.createDocumentFragment()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末书幕,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子揽趾,更是在濱河造成了極大的恐慌按咒,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件但骨,死亡現(xiàn)場(chǎng)離奇詭異励七,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)奔缠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)掠抬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人校哎,你說(shuō)我怎么就攤上這事两波。” “怎么了闷哆?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵腰奋,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我抱怔,道長(zhǎng)劣坊,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任屈留,我火速辦了婚禮局冰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘康二。我一直安慰自己,他們只是感情好沫勿,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著产雹,像睡著了一般诫惭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上洽故,一...
    開(kāi)封第一講書(shū)人閱讀 49,144評(píng)論 1 285
  • 那天盗誊,我揣著相機(jī)與錄音,去河邊找鬼哈踱。 笑死荒适,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的开镣。 我是一名探鬼主播刀诬,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼陕壹!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起糠馆,我...
    開(kāi)封第一講書(shū)人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤怎憋,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后绊袋,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡癌别,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了展姐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片姓建。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡缤苫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出活玲,到底是詐尸還是另有隱情,我是刑警寧澤舒憾,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站丁溅,受9級(jí)特大地震影響探遵,放射性物質(zhì)發(fā)生泄漏窟赏。R本人自食惡果不足惜箱季,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望藏雏。 院中可真熱鬧,春花似錦赚瘦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)杜恰。三九已至仍源,卻和暖如春心褐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背笼踩。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留掘而,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓袍睡,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親斑胜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

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

  • 目前typescript已經(jīng)是前端的一個(gè)加分項(xiàng)掺炭; 微軟發(fā)明的TypeScript凭戴,JavaScript是網(wǎng)景公司發(fā)...
    MrTon_1965閱讀 608評(píng)論 0 0
  • typescript筆記[https://www.cnblogs.com/liea/p/13393842.html...
    硅谷干貨閱讀 296評(píng)論 0 0
  • 前言 2019年,TypeScript火遍大街小巷么夫,越來(lái)越多的程序員希望在新的項(xiàng)目中學(xué)習(xí)和使用TypeScript...
    克里斯先生20閱讀 1,099評(píng)論 1 5
  • 這張圖來(lái)自 TypeScript 官網(wǎng)提到了說(shuō) TypeScript 是 JavaScript 的超集魏割!它有自己的...
    嘉奇閱讀 381評(píng)論 0 2
  • 官方:擁有類(lèi)型系統(tǒng)的javascript的超集钢颂,可以編譯成純javascript 注意三個(gè)點(diǎn):類(lèi)型檢查(編碼的時(shí)候...
    我性本傲閱讀 272評(píng)論 0 0