TypeScript語(yǔ)言規(guī)范與基本應(yīng)用

TypeScript解決JavaScript類(lèi)型系統(tǒng)的問(wèn)題嗎,大大提高代碼的可靠程度

TypeScript是JavaScript的超集(擴(kuò)展JavaScript語(yǔ)法串远,提供更強(qiáng)大的類(lèi)型系統(tǒng)),會(huì)被編譯為JavaScript類(lèi)型

缺點(diǎn):

  1. 語(yǔ)言本身多了很多概念,增強(qiáng)學(xué)習(xí)成本(TypeScript屬于漸進(jìn)式)
  2. 項(xiàng)目初期,TypeScript會(huì)增加一些成本(長(zhǎng)久來(lái)說(shuō)很重要)
TypeScript安裝
  1. yarn init --yes初始化項(xiàng)目
  2. yarn add typeScript --dev 作為開(kāi)發(fā)依賴(lài)斯入,此時(shí)node_modules/.bin/tsc文件用于編譯typeScript
  3. yarn tsc xxx.ts 進(jìn)行編譯
  4. yarn tsc --init生成.tsconfig.json文件
  5. 按需修改配置文件(rootDir為ts文件目錄,outDir為輸出js文件目錄)
  6. 此時(shí)直接使用yarn tsc就可進(jìn)行指定目錄編譯
TypeScript使用指南
  • 原始類(lèi)型

    const a: string = 'foobar'
    const b: number = 100 // NaN Infinity
    const c: boolean = true // false
    // 在非嚴(yán)格模式(strictNullChecks)下蛀蜜,
    // string, number, boolean 都可以為空
    // const d: string = null
    // const d: number = null
    // const d: boolean = null
    const e: void = undefined
    const f: null = null
    const g: undefined = undefined
    // Symbol 是 ES2015 標(biāo)準(zhǔn)中定義的成員刻两,
    // 使用它的前提是必須確保有對(duì)應(yīng)的 ES2015 標(biāo)準(zhǔn)庫(kù)引用
    // 也就是 tsconfig.json 中的 lib 選項(xiàng)必須包含 ES2015
    const h: symbol = Symbol()
    // Promise
    // const error: string = 100
    
  • 作用域問(wèn)題

    // a.js
    const a: string = 'a' // 默認(rèn)文件中的成員會(huì)作為全局成員
    // b.js
    const a: number = 2 // 無(wú)法重新聲明塊范圍變量“a”。
    // 解決
    // 1.立即執(zhí)行函數(shù)
    (function() {
        const a: number  = 2
    })()
    // 2.使用export 把當(dāng)前文件變?yōu)槟K
    const a: number = 2
    export {}
    
  • Object類(lèi)型

    // 指所有非原始類(lèi)型
    const foo: object = function() {}
    // 普通對(duì)象類(lèi)型實(shí)現(xiàn) 更專(zhuān)業(yè)的使用接口類(lèi)型實(shí)現(xiàn)
    const obj: { foo: number, bar: string } = { foo: 123, bar: 'a' }
    
  • 數(shù)組類(lèi)型

    // 兩種定義方式
    const arr: number[] = [1,2,3]
    const arr: Array<number> = [1,2,3]
    
    function sum(...args: number[]) {
        // 如果是 JS滴某,需要判斷是不是每個(gè)成員都是數(shù)字
      return args.reduce((prev, current) => prev + current)
    }
    sum(1,2,3)
    
  • 元組類(lèi)型

    // 明確元素?cái)?shù)量以及每個(gè)元素類(lèi)型的數(shù)組
    const tuple: [number, string] = [12, 'wang']
    const [age, name] = tuple
    // 編譯為js后實(shí)際相當(dāng)于以下代碼
    // const age = tuple[0]
    // const name = tuple[1]
    // Object.entries獲取到每個(gè)鍵值對(duì)就是元組 固定長(zhǎng)度 固定類(lèi)型
    const entries: [string, number][] = Object.entries({
      foo: 123,
      bar: 456
    })
    const [key, value] = entries[0]
    
  • 枚舉類(lèi)型

    // 對(duì)象模擬實(shí)現(xiàn)枚舉
    const PostStatus = {
      Draft: 0,
      Unpublished: 1,
      Published: 2
    }
    enum PostStatus {
      Draft, // 不設(shè)置值時(shí)默認(rèn)從0開(kāi)始遞增 相當(dāng)于Draft = 0,Unpublished = 1,Published = 2
      Unpublished,
      Published
    }
    enum PostStatus {
      Draft = 6, // 相當(dāng)于Draft = 6,Unpublished = 7,Published = 8
      Unpublished,
      Published
    }
    // 常量枚舉磅摹,不會(huì)侵入編譯結(jié)果
    const enum PostStatus {
      Draft,
      Unpublished,
      Published
    }
    
  • 函數(shù)類(lèi)型

    // 函數(shù)聲明
    // 輸入輸出類(lèi)型限制
    function fun1(a: number, b: number): string {
      return 'fun1'
    }
    fun1(1, 2)
    // 如果一個(gè)參數(shù)可有可無(wú)
    function fun1(a: number, b?: number): string {
      return 'fun1'
    }
    function fun1(a: number, b: number = 2): string {
      return 'fun1'
    }
    // 如果需要傳入多個(gè)參數(shù)
    function fun1(a: number, b: number = 2, ...rest: number[]): string {
      return 'fun1'
    } 
    // 函數(shù)表達(dá)式
    const fun2: (a: number, b: number) => string = function (a: number,b: number): string {
      return 'fun2'
    }
    
  • 任意類(lèi)型

    function stringify(value: any) {
      return JSON.stringify(value)
    }
    stringify('string')
    stringify(100)
    stringify(true)
    
    let foo: any = 'string'
    foo = 100
    foo.bar()
    // any時(shí)類(lèi)型不安全的
    
  • 聯(lián)合類(lèi)型

    // 聯(lián)合類(lèi)型 通過(guò)|將變量設(shè)置為多種值
    let strOrNum: string | number = 2
    strOrNum = 'sdf'
    
    let arr: string[] | number[]
    arr = [1, 2, 3]
    arr = ['foo', 'bar', 'baz']
    // 函數(shù)參數(shù)
    function add(name: string | string[]): void { }
    
  • 隱式類(lèi)型推斷

    let age = 12
    // typeScript推斷此類(lèi)型為number
    age = 'string' // 不能將類(lèi)型“string”分配給類(lèi)型“number”
    // 盡可能給每個(gè)變量添加類(lèi)型
    
  • 類(lèi)型斷言

    const nums = [12, 13, 14]
    const res = nums.find(i => i > 0)
    // 類(lèi)型斷言
    const num1 = res as number
    // const num1 = <number>res // JSX下不能使用
    const square = res * res
    
  • 接口

    // 規(guī)范或契約 約定一個(gè)對(duì)象的結(jié)構(gòu)
    interface Post {
      title: string
        content: string
        subtitle?: string // 可選成員
        readonly summary: string // 只讀成員
    }
    function printPost(post: Post) {
        console.log(post.title)
        console.log(post.content)
    }
    printPost({
        title: 'hello',
        content: 'China'
    })
    // 動(dòng)態(tài)對(duì)象 定義時(shí)無(wú)法知道有哪些具體成員
    interface Cache {
      [prop: string]: string
    }
    const cache: Cache = {}
    cache.foo = 'value1'
    cache.bar = 'value2'
    
  • 類(lèi)的基本使用

    // 描述一類(lèi)具體事物的抽象特征
    // ES6之前,通過(guò)函數(shù) + 原型模擬實(shí)現(xiàn)類(lèi)
    // TypeScript增強(qiáng)了class的相關(guān)語(yǔ)法
    // 訪(fǎng)問(wèn)修飾符 private私有屬性 只能在當(dāng)前訪(fǎng)問(wèn) public共有屬性 protected只能在繼承的子類(lèi)中訪(fǎng)問(wèn) 相比于private允許繼承
    // readonly 只讀屬性 不能被修改
    class Person {
        public name:string
        private age: number
        protected readonly gender: boolean
        constructor (name: string, age: numberr) {
            this.name = name
            this.age = age
        }
      sayHi (msg: string): void {
          console.log(`I am ${this.name}, ${msg}`)
        }
    }
    
  • TypeScript類(lèi)與接口

    // 使用接口明確強(qiáng)制一個(gè)類(lèi)去符合某種契約
    // 接口描述類(lèi)的公共部分
    // 一個(gè)接口盡量只定義一個(gè)方法
    interface Eat {
      eat(food: string):void
    }
    interface Run {
      run(distance: number): void
    }
    class Animal implements Eat, Run {
      eat(food: string): void {
          console.log(`大口吃:${food}`)
      }
      run(distance: number): void {
        console.log(`爬行:${distance}`)
      }
    }
    class Person implements Eat, Run {
      eat(food: string): void {
        console.log(`細(xì)嚼慢咽的吃:${food}`)
      }
      run(distance: number): void {
        console.log(`行走:${distance}`)
      }
    }
    
  • 抽象類(lèi)

    // abstract修飾 只能被繼承 不能使用new創(chuàng)建實(shí)例
    // 有抽象方法的類(lèi)必須被聲明為抽象類(lèi)
    // 和接口相似 抽象方法也是定義但不實(shí)現(xiàn) 相比接口 抽象類(lèi)可以包含成員的實(shí)現(xiàn)細(xì)節(jié)
    abstract class Animal {
      eat(food: string): void {
          console.log(`大口吃:${food}`)
        }
      abstract run(distance: number): void // 抽象方法 不包含具體實(shí)現(xiàn) 須在派生類(lèi)中實(shí)現(xiàn)
    }
    class Dog extends Animal {
      run(distance: number): void {
          console.log('四腳爬行', distance)
        }
    }
    
    const d = new Dog()
    d.eat('嗯西馬')
    d.run(100)
    
  • 泛型

    // 聲明時(shí)不指定類(lèi)型 調(diào)用時(shí)在指定類(lèi)型
    // 使用泛型創(chuàng)建可重用的組件
    function createStringArray (length: number, value: string): string[] {
      return Array<string>(length).fill(value)
    }
    function createNumberArray(length: number, value: number): number[] {
      return Array<number>(length).fill(value)
    }
    const res = createStringArray(4, 'ff')
    console.log(res);
    const res1 = createNumberArray(4, 100)
    console.log(res1);
    // 使用泛型的方式
    function createArray<T>(length: number, value: T): T[] {
      return Array<T>(length).fill(value)
    }
    const res2 = createArray<string>(3, 'foo')
    const res3 = createArray<number>(3, 45)
    console.log(res2);
    console.log(res3);
    
  • 類(lèi)型聲明

    ? 第三方npm模塊 這些npm模塊不一定通過(guò)typeScript編寫(xiě) 無(wú)法使用TypeScript類(lèi)型檢查等功能霎奢;需將庫(kù)里的函數(shù)和方法體去掉只保留導(dǎo)出類(lèi)型聲明户誓,產(chǎn)出一個(gè)描述JavaScript庫(kù)和模塊信息的聲明文件,引入此聲明文件 就可以借用TypeScript的各種特性來(lái)使用庫(kù)文件

    • 引入模塊對(duì)應(yīng)的類(lèi)型聲明模塊@types/xx

      // 安裝lodash的類(lèi)型聲明模塊就可正常使用 yarn add @types/lodash --dev
      import { camelCase } from 'lodash'
      const res = camelCase('hello typed')
      
image-20210112145412070.png
  • 內(nèi)部已集成類(lèi)型聲明文件

    // 內(nèi)部已經(jīng)繼承了類(lèi)型聲明文件 所以不用在聲明
    import qs from 'query-string'
    qs.parse('?key=value&key2=value2')
    
  • 如果沒(méi)有類(lèi)型聲明模塊時(shí)幕侠,自定義declare 關(guān)鍵字來(lái)定義類(lèi)型

    // 以$符號(hào)為例
    // 需要使用declare關(guān)鍵字來(lái)定義它的類(lèi)型 幫助TypeScript判斷我們傳入的參數(shù)類(lèi)型
    declare const $: (selector: string) => any
    $('#foo')
    
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末帝美,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子晤硕,更是在濱河造成了極大的恐慌悼潭,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件舞箍,死亡現(xiàn)場(chǎng)離奇詭異舰褪,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)疏橄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)占拍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人捎迫,你說(shuō)我怎么就攤上這事晃酒。” “怎么了立砸?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵掖疮,是天一觀的道長(zhǎng)初茶。 經(jīng)常有香客問(wèn)我颗祝,道長(zhǎng)浊闪,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任螺戳,我火速辦了婚禮搁宾,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘倔幼。我一直安慰自己盖腿,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布损同。 她就那樣靜靜地躺著翩腐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪膏燃。 梳的紋絲不亂的頭發(fā)上茂卦,一...
    開(kāi)封第一講書(shū)人閱讀 49,929評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音组哩,去河邊找鬼等龙。 笑死,一個(gè)胖子當(dāng)著我的面吹牛伶贰,可吹牛的內(nèi)容都是我干的蛛砰。 我是一名探鬼主播,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼黍衙,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼泥畅!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起琅翻,我...
    開(kāi)封第一講書(shū)人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤涯捻,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后望迎,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體障癌,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年辩尊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了涛浙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡摄欲,死狀恐怖轿亮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情胸墙,我是刑警寧澤我注,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站迟隅,受9級(jí)特大地震影響但骨,放射性物質(zhì)發(fā)生泄漏励七。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一奔缠、第九天 我趴在偏房一處隱蔽的房頂上張望掠抬。 院中可真熱鬧,春花似錦校哎、人聲如沸两波。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)腰奋。三九已至,卻和暖如春抱怔,著一層夾襖步出監(jiān)牢的瞬間氛堕,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工野蝇, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留讼稚,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓绕沈,卻偏偏與公主長(zhǎng)得像锐想,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子乍狐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350

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