不知不覺typescript的學習快兩個月了,適當作一下整理。javascript
在剛開始學習typescript時候,揮斥方遒地敲了好多字!給本身羅列了幾個研究目標:html
類型系統前端
工具vue
在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
社區github
平常體驗typescript
更多npm
懷揣着這張意氣風發的Map,開始了!
說白了,typescript就是提供了一層類型系統,始發站天然而然地選擇了這裏。
自誇英語很好的我剛開始嚼起了官方英文文檔 ,嚼得我頭皮發麻,一個是內容過於詳細,沒有項目實踐很快就忘記了,另外一個是文檔缺少組織性,還有一些晦澀的章節對新手不太友好,好比 namespaces 、Namespaces 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
那差異在哪裏:
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];
複製代碼
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 };
複製代碼
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"
}
複製代碼
其餘再好比 unknown
和 any
的區別(這篇文章講的很好:mariusschulz: the-unknown-type-in-typescript )、Type Widening 和 Narrowing的各個招數等等,這裏不細節展開了。
之後忘記了,策略能夠是:我的整理資料 => Playground Example => 官方文檔
typescript是使用JavaScript新特性很好的土壤,因而調研了一下ES2020。
這在另外一篇文章中有詳細說明,移步:Hello ES2020 & ES2019!。
用到比較多的是可選鏈(Optional chaining)、空值合併運算符(Nullish coalescing operator)。
畢竟是微軟一家人,支持力度是至關能夠的,詳細說明在這裏: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就不說了,以前看Youtube上一個演講視頻 Anders Hejlsberg 提到他們團隊專門有一人來作playground這個項目。
剛開始的時候把DT放在了工具,瞭解事後更以爲應該放在社區。
咱們知道雖然 TypeScript 勢頭很猛,但不少第三方主流的庫仍是JavaScript編寫的,這樣怎麼使它也享用vscode的體驗提高呢(或者說,在typescript項目中使用)?答案是寫聲明文件,就是常常看到的.d.ts
後綴。
聲明文件有了以後,如何讓它們起做用,即如何發佈呢,有兩種方式:
因此 DefinitelyTyped 就是這樣一個社區,把經常使用模塊聲明文件提交,它會發布到@types organization,它就成了這樣的一個集合。
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
回到最初設定的目標(簡單調整了一下),作一下覆盤:
接下來關於typescript的研究/學習話題還有不少,羅列一下第二張Map。
在學習之初,這篇文章 TypeScript-一種思惟方式 清晰明確的觀點給了我不少啓發 ,在後面的學習過程也更加感同身受。
主要有3點:
學習一項新的技能,清楚其邊界很重要,相關的細節知識則能夠在後續的使用過程當中逐步的瞭解。咱們都知道,TS 是 JS 的超集,因此學習 TS 的第一件事情就是要找到「超」的邊界在哪裏
從語言自己而言,TS的邊界在引入了一套類型系統。TS相關工具的助力,使得編程體驗更加絲滑;
思惟方式改變-明確的模塊抽象過程:在開始一個模塊碼代碼以前,會天然而然考慮輸入值和返回值,作抽象和拓展;
思惟方式改變-更自信的寫前端代碼:TS會捕捉容易被忽略的狀況,也許這就是一個bug
另外推薦兩個連接: