TypeScript學習小記

不知不覺typescript的學習快兩個月了,適當作一下整理。javascript

開始

在剛開始學習typescript時候,揮斥方遒地敲了好多字!給本身羅列了幾個研究目標:html

  1. 類型系統前端

    1. typescript帶來的類型系統包含哪些內容,哪些是在原有基礎作的加法,哪些是新增的概念,哪些,好比 interface、enum、unions等;
    2. 這些類型系統有哪些實踐,是如何幫助咱們提升代碼的健壯性和可預計性(類型系統的做用)
  2. 工具vue

    1. typescript和編輯器的集成(好比vscode),帶給了咱們編程體驗上的提高,好比更好的文檔說明、提示、自動糾正等,這些工具的體驗是怎麼樣的,如何更好地使用這些工具
    2. playground、DefinitelyTyped是什麼
  3. 在ts官網首頁有這樣一句話:java

    When new features have reached stage 3, then they are ready for inclusion in TypeScript.react

    ts致力於和標準一塊發展,提供對新特性更好的支持,好比 Optional Chaining、Nullish coalescing Operator等ES2020特性,探索挖掘有哪些特性是那麼鮮爲人知,又倒是能夠給開發帶來幫助的git

  4. 社區github

    1. typescript和eslint的合做,lint typescript代碼是用eslint仍是tslint
    2. typescript和babel的合做,babel是一個compiler,typescript也有這方面的職能,雙方有衝突。typescript有尋求babel合做,把compiler的職責專門交給babel,如今落地如何?
    3. typescript有哪些社區,stackoverflow、discord等
  5. 平常體驗typescript

    1. 在平常開發中,next+react+ts下的ts體驗如何,踩過什麼坑
    2. 體驗的通常流程如何,用到的比較多的是什麼
    3. tsconfig等配置
  6. 更多npm

    1. vue3.0對typescript的支持到什麼程度了
    2. typescript背後AST轉換等等
    3. typescript和幾個競爭對手flow、purescript等對比

懷揣着這張意氣風發的Map,開始了!

學習

類型系統

說白了,typescript就是提供了一層類型系統,始發站天然而然地選擇了這裏。

自誇英語很好的我剛開始嚼起了官方英文文檔 ,嚼得我頭皮發麻,一個是內容過於詳細,沒有項目實踐很快就忘記了,另外一個是文檔缺少組織性,還有一些晦澀的章節對新手不太友好,好比 namespacesNamespaces and Modules 。(如今改版後的The TypeScript Handbook比老版要好不少)

因而臨時改變了策略,從 playground-exmaple 打起,有基本認識後,有須要再去詳細文檔查看!

整個類型系統能夠分爲兩部分:提高JavaScript體驗( improves working with JavaScript)、擴展JavaScript安全性和工具(extends JavaScript to add more safety and tooling)。作了簡單的梳理:

這裏碰到了的一些概念,在一開始不太好接受。

好比 TypeScript 的類型系統被稱爲結構類型系統,也就是官方文檔的這段描述:

One of TypeScript’s core principles is that type checking focuses on the shape that values have. This is sometimes called 「duck typing」 or 「structural subtyping」.

看下面的demo:champion 函數須要的參數類型是Team,而傳入的是DetailedTeam,這是容許的,由於ts的結構類型系統僅比較DetailedTeam是否包含Team的結構

interface Team {
  name: string
  city: string
}

interface DetailedTeam {
  name: string
  city: string
  mascot: string
}

function champion(team: Team) {
  const { name, city } = team

  console.log(`The ${name} from ${city} won the NBA 2020 championship!`)
}

let teamA: DetailedTeam = {
  name: 'Rockets',
  city: 'Houston',
  mascot: 'bear'
}

champion(teamA)
複製代碼

有一個例外是當賦值操做的是函數,看下面的demo:是容許入參少的 createBall函數複製給 createSphere 函數

let createBall = (diameter: number) => ({ diameter });
let createSphere = (diameter: number, useInches: boolean) => {
  return { diameter: useInches ? diameter * 0.39 : diameter };
};

createSphere = createBall;  //👌
createBall = createSphere;  //Type '(diameter: number, useInches: boolean) => { diameter: number; }' is not assignable to type '(diameter: number) => { diameter: number; }'
複製代碼

再好比比較有熱度的話題: interface 和 type alias(類型別名)的區別。

在typescript中,interface和type均可以來表達對象結構、函數。它們也都支持擴展,interface能夠繼承interface,也能夠繼承type,反過來type也同樣。固然寫法不同:

Typescript doc example: Types vs Interfaces

那差異在哪裏:

  1. type alias除了表達對象、函數外,還支持表達其餘類型,好比 unions、tuples、primitives,這個能力interface不具有

    // primitive
    type Name = string;
    
    // object
    type PartialPointX = { x: number; };
    type PartialPointY = { y: number; };
    
    // union
    type PartialPoint = PartialPointX | PartialPointY;
    
    // tuple
    type Data = [number, string];
    複製代碼
  2. interface容許定義屢次,結果取交集,而type alias這樣作會報錯

    // These two declarations become:
    // interface Point { x: number; y: number; }
    interface Point { x: number; }
    interface Point { y: number; }
    
    const point: Point = { x: 1, y: 2 };
    複製代碼
  3. type alias內支持 in 操做,而 interface 不支持

    //demo1
    type Partial<T> = {
        [P in keyof T]?: T[P];
    };
    
    //demo2
    type Keys = "firstname" | "surname"
    
    type DudeType = {
      [key in Keys]: string
    }
    
    interface DudeInterface {
      [key in Keys]: string
    }
    
    const test: DudeType = {
      firstname: "Pawel",
      surname: "Grzybek"
    }
    複製代碼

其餘再好比 unknownany 的區別(這篇文章講的很好:mariusschulz: the-unknown-type-in-typescript )、Type Widening 和 Narrowing的各個招數等等,這裏不細節展開了。

之後忘記了,策略能夠是:我的整理資料 => Playground Example => 官方文檔

ES2020

typescript是使用JavaScript新特性很好的土壤,因而調研了一下ES2020。

這在另外一篇文章中有詳細說明,移步:Hello ES2020 & ES2019!

用到比較多的是可選鏈(Optional chaining)、空值合併運算符(Nullish coalescing operator)。

工具

vscode對TypeScript支持

畢竟是微軟一家人,支持力度是至關能夠的,詳細說明在這裏:TypeScript in Visual Studio Code

耳熟能詳的有 智能感知(IntelliSense)、懸浮可查看詳細說明(Hover information),再提兩個平常開發經常使用的:

  • code navigation

    • F12 : 在新頁面,查看選中內容的源碼定義
    • Alt/Opt + F12:在當前頁內嵌窗口,查看選中內容的源碼定義
    • shift + F12 :在當前頁內嵌窗口,查看選中內容的引用
    • win/command+F12 :查看interface應用/實例
  • organize imports: 整理import語句順序、移除沒有使用的

    • 快捷鍵:shift+Opt/Alt+o

    • 若是須要保存時起做用,配置:

      {
        "editor.codeActionsOnSave": {
          "source.organizeImports": true
        }
      }
      複製代碼

這裏額外提一下插件:JavaScript and TypeScript Nightly ,使用 typescript@next 做爲vscode 內置ts版本,享用最新最絲滑的ts編程體驗。

playground

playground就不說了,以前看Youtube上一個演講視頻 Anders Hejlsberg 提到他們團隊專門有一人來作playground這個項目。

社區

Definitely Typed

剛開始的時候把DT放在了工具,瞭解事後更以爲應該放在社區。

咱們知道雖然 TypeScript 勢頭很猛,但不少第三方主流的庫仍是JavaScript編寫的,這樣怎麼使它也享用vscode的體驗提高呢(或者說,在typescript項目中使用)?答案是寫聲明文件,就是常常看到的.d.ts後綴。

聲明文件有了以後,如何讓它們起做用,即如何發佈呢,有兩種方式:

  1. 和npm包捆綁在一塊兒(內置類型定義文件),好比Vue的types文件夾
  2. 提交到DefinitelyTyped,由它發佈到@types organization,經過 npm i @types/xxxx 安裝,這樣其餘人也能夠對JavaScript庫作貢獻

因此 DefinitelyTyped 就是這樣一個社區,把經常使用模塊聲明文件提交,它會發布到@types organization,它就成了這樣的一個集合。

TypeScript與ESLint

TSLint已經退出Lint TypeScript舞臺:

:warning: TSLint has been deprecated as of 2019. Please see this issue for more details: Roadmap: TSLint → ESLint. typescript-eslint is now your best option for linting TypeScript.

這篇文章很清晰地介紹了在TypeScript+React項目中使用ESLint和Prettier標準化代碼要作的全部事情:Using ESLint and Prettier in a TypeScript Project

若是使用到了hooks,須要增長hooks的lint規則:eslint-plugin-react-hooks

覆盤

回到最初設定的目標(簡單調整了一下),作一下覆盤:

  • 類型系統
  • 工具
    • vscode支持
    • playground
  • javascript語言新特性
  • 社區
    • typescript與ESLint
    • typescript與babel
    • Definitely Typed
    • stackoverflow、discord等論壇
  • 更多
    • vue3.0對typescript的支持、體驗
    • typescript背後AST轉換等等
    • typescript和幾個競爭對手flow、purescript等對比

NEXT

接下來關於typescript的研究/學習話題還有不少,羅列一下第二張Map。

小結

在學習之初,這篇文章 TypeScript-一種思惟方式 清晰明確的觀點給了我不少啓發 ,在後面的學習過程也更加感同身受。

主要有3點:

  1. 學習一項新的技能,清楚其邊界很重要,相關的細節知識則能夠在後續的使用過程當中逐步的瞭解。咱們都知道,TS 是 JS 的超集,因此學習 TS 的第一件事情就是要找到「超」的邊界在哪裏

    從語言自己而言,TS的邊界在引入了一套類型系統。TS相關工具的助力,使得編程體驗更加絲滑;

  2. 思惟方式改變-明確的模塊抽象過程:在開始一個模塊碼代碼以前,會天然而然考慮輸入值和返回值,作抽象和拓展;

  3. 思惟方式改變-更自信的寫前端代碼:TS會捕捉容易被忽略的狀況,也許這就是一個bug

另外推薦兩個連接:

連接

相關文章
相關標籤/搜索