【TS】學習總結

01-TypeScript編譯環境

TypeScript全域性安裝

  1. npm install typescript -g
  2. tsc --version //檢視版本,安裝成功

TypeScript執行環境

  • 常規路徑

    1. tsc demo.ts//demo.ts -> demo.js
    2. 執行js檔案
  • ts-node(類似於node執行js)

    1. npm install ts-node -g
    2. //ts-node依賴tslib、@types/node
    3. npm install tslib @types/node -g
    4. ts-node demo.ts
  • webpack工程環境

    ts-webpack -- coderwhy老師

    1. - mkdir demo & cd demo
    2. npm init
    3. npm install typescript
    4. tsc --init
    5. npm install webpack webpack-cli webpack-dev-server -D
    6. npm install ts-loader -D
    7. npm install html-webpack-plugin -D
    8. - 配置package.json
    9. - 配置webpack.config.js
    10. ...

02-TypeScript資料型別

資料定義語法

const/let/var name(: Type) = value;

不標明Type則會進行型別推導

基本資料型別

...

Array型別

推薦(TSLint):

  1. const names1: string[] = ["why", "abc", "cba"];
  2. const names2: Array<string> = ["why", "abc", "cba"];

陣列型別元素型別相同。

object型別

  1. // 使用型別推斷
  2. const obj = {
  3. name:"afs",
  4. age: 23
  5. };

symbol型別&null型別&undefined型別

...


TypeScript新增資料型別

enum型別

  1. enum Direction {
  2. EAST,
  3. WEST,
  4. NORTH,
  5. SOUTH,
  6. }
  7. const d1 = Direction.EAST; // 0
  8. const d2 = Direction.NORTH; // 2
  9. // 指定值,未賦值的依次遞增
  10. enum Direction {
  11. EAST = 10,
  12. WEST = 20,
  13. NORTH,
  14. SOUTH = 40,
  15. }
  16. /*
  17. console.log(Direction);
  18. {
  19. '10': 'EAST',
  20. '20': 'WEST',
  21. '21': 'NORTH',
  22. '30': 'SOUTH',
  23. EAST: 10,
  24. WEST: 20,
  25. NORTH: 21,
  26. SOUTH: 30
  27. }
  28. */
  29. console.log(Direction[21]); // NORTH

tuple型別

相較於陣列,元素型別不同則為元組。

  1. const num = [111, "sadfdsa"];
  2. num.push(123)
  3. num.push("asdfs")
  4. num // [ 111, 'sadfdsa', 123, 'asdfs' ]

any型別

相對於保留js特性的變數(型別不確定)。

如果需要某個變數的型別不固定,可以顯式定義any。

void型別

如果一個函式沒有返回值,那麼它的返回值型別就是void。

  • 函式不顯式定義返回型別,則會對返回值進行型別推導,沒有返回值則返回undefined
  • 如果定義為void,預設不能有返回值,但可以顯式返回undefined
  • 如果定義為any,可以返回任何型別
  • 如果定義為其他特定型別,則必須有返回值且型別相同,比如undefined則必須顯式返回undefined
  1. function a(): undefined{
  2. console.log(1)
  3. }// 報錯

never型別

never 表示永遠不會發生的型別。

如:一個從來不會有返回值的函式(死迴圈),一個總是會丟擲錯誤的函式。(一切不可能執行到的部分均可以限定為never型別)

  1. function foo(x: string | number ): boolean {
  2. if (typeof x === 'string') {
  3. return true;
  4. } else if (typeof x === 'number') {
  5. return false;
  6. }
  7. // 如果 前面的判斷有遺漏 ,這會報錯:
  8. // - 不是所有條件都有返回值 (嚴格模式下)
  9. // - 或者檢查到無法訪問的程式碼
  10. // 但是由於 TypeScript 執行永遠不會被訪問的 `never` 型別
  11. // 你可能會用它來做安全或者詳細的檢查。
  12. const check: never = x;
  13. }
  14. // 如果有開發人員需要zx型別

unknown型別

unknown 型別含義類似於any

unknown 型別不能賦值給除了 unknownany 的其他任何型別,使用前必需顯式進行指定型別,或是在型別縮小情況下能夠隱式地進行型別推斷的情況。

函式型別

  1. const func: (n: number, s: string) => void = function func(m: number, n: string): void{
  2. //code block
  3. }

類型別名

  1. type newType = number|string;

字面量型別

  1. let m: 'message' = "message";
  2. //m型別則為確定的'message'型別
  3. m = 'other';//報錯

字面量推斷

  1. function func(m: "a"|"b"|"c"){}
  2. let a = "a";
  3. func(a);//報錯
  4. //reason: a: string,m需要字面量型別,即使a="a"可以避免a更改為其他字串
  5. // => 改成
  6. func(a as "a"); //或
  7. const a = "a"; //或
  8. const a = "a" as const;

03-TypeScript中函式

有一部分可見02-...[void型別]部分。

  1. function func(m: type, n: type): type{
  2. //code block
  3. }
  4. // 如果引數type不寫會預設是any,返回值type會根據函式體返回值自動型別推斷

匿名函式會根據上下文自動推斷引數型別。

  1. const array = [1, 2, 3];
  2. array.forEach(item => {
  3. //code block
  4. })
  5. //此處item會上下文進行型別推斷: number

物件型別

  1. function func(obj: {m: number, n: string}){}

可選型別

  1. function func(m?: number){}
  2. //m可選

聯合型別

  1. function func(m: number|string){}
  2. //m為其中型別之一
  3. //使用前需要型別縮小或型別斷言

型別斷言as

將不確定的型別轉為更確定的型別。

  1. //強制轉換
  2. const s2n = ("string" as unknown) as number;
  3. ...

非空型別斷言!

  1. function func(m?: string){
  2. return m.length;
  3. }
  4. //編譯報錯
  5. //改成 => 逃過編譯階段報錯
  6. function func(m?: string){
  7. return m!.length;
  8. }

可選鏈

  1. //上面程式碼可以改成
  2. function func(m?: string){
  3. return m?.length;
  4. }
  5. //如果m不存在則短路直接返回undefined

剩餘引數

  1. function func(...args: number[]){}

詳解Typescript裡的This - 知乎 (zhihu.com)

函式過載

  1. function sum(m: number, n: number): number;
  2. function sum(m: string, n: string): string;
  3. function sum(m: any, n: any): any{
  4. //code block
  5. }

04-TypeScript型別縮小

將不確定的型別進行類型範圍縮小。

typeof

  1. function func(m: number|string){
  2. if(typeof m === "number") {}
  3. else {} //number
  4. }

平等縮小

  1. //switch
  2. function func(m: "a"|"b"){
  3. switch (m) {
  4. case 'a': break;
  5. case 'b': break;
  6. }
  7. }
  8. //===...
  9. function func(m: "a"|"b"){
  10. if(m === "a") {}
  11. //...
  12. }

instanceof

  1. function func(m: Data:string){
  2. if(m instanceof Data) {}
  3. }

in

  1. type Fish = {swim: () => void}
  2. type dog = {run: () => void}
  3. function func(animal: Fish|dog){
  4. if("swim" in animal) {} //Fish
  5. }

05-TypeScript類

繼承:extends

  1. class Parent{
  2. constructor(){}
  3. }
  4. class Child extends Parent{
  5. constructor(){
  6. super();
  7. }
  8. }

修飾符

public、protected、private、static

readonly

  1. class Parent{
  2. readonly xxx;
  3. //xxx只能在 構造器 或 欄位定義時 賦值
  4. constructor(){}
  5. }

存取器

  1. class Parent{
  2. set name(name){}
  3. get name(){}
  4. }

抽象類abstract

...略...

06-TypeScript介面

  1. //物件型別
  2. interface Obj{
  3. name: string,
  4. age?: number,
  5. readonly sex: boolean
  6. }
  7. //索引型別
  8. interface Index{
  9. [index: number]: string
  10. }
  11. //函式型別
  12. interface Func{
  13. (n: number, m: number): number
  14. }

繼承

介面支援多繼承,類只能單一繼承。

多型(面向介面程式設計)

...略...

Freshness

Freshness | 深入理解 TypeScript (jkchao.github.io)

  1. interface IPerson{
  2. name: string
  3. }
  4. const p: IPerson = {
  5. name: "a",
  6. aname: "a"
  7. } //報錯
  8. //在p的賦值過程中,TypeScript對 物件字面量 進行嚴格檢查

泛型

  1. function foo<T>(arg: T): T {}
  2. // 顯式型別定義
  3. foo<string>("abc")
  4. // 隱式型別推導
  5. foo("abc")

泛型約束

  1. interface ILength{
  2. length: number
  3. }
  4. function getLength<T extends ILength>(args: T){
  5. return args.length;
  6. }
  7. getLength("aaa");
  8. getLength([1, 2]);
  9. getLength({length: 10});

07-TypeScript模組化開發

模組化

利用ES Module或CommonJS使檔案成為一個獨立的模組。

  1. // ~/a.ts
  2. const a = 1;
  3. const b = 1;
  4. // ~/b.ts
  5. const a = 1;
  6. const b = 1;
  7. // ↑報錯,衝突
  8. -------------
  9. // ~/a.ts
  10. const a = 1;
  11. const b = 1;
  12. // ~/b.ts
  13. const a = 1;
  14. export const b = 1;
  15. // ↑ok

namespace名稱空間

namespace允許在模組內部進行更小粒度的作用域劃分。

型別查詢規則

.d.ts檔案

進行型別宣告(declare),用來做型別檢測。

內建型別宣告

內建JavaScript執行時的一些標準化API的宣告檔案。

TypeScript/lib at main · microsoft/TypeScript (github.com)

外部定義型別宣告

第三方庫的型別宣告,有時安裝第三方庫時沒有內建型別宣告,需要自行下載或配置。

DefinitelyTyped/DefinitelyTyped: The repository for high quality TypeScript type definitions. (github.com)

TypeScript: Search for typed packages (typescriptlang.org)

自定義型別宣告

  1. //變數
  2. let name = "name"; //.ts
  3. declare let name: string; //.d.ts
  4. //函式
  5. function foo(){}; //.ts
  6. declare function foo(): void; //.d.ts
  7. //類
  8. class xxx{}; //.ts
  9. declare class xxx{}; //.d.ts
  10. //模組
  11. export defualt xxx; //.ts
  12. declare module "xxx" {}; //.d.ts
  13. //名稱空間
  14. declare namespace ${
  15. function ajax(): void
  16. }//.d.ts
  17. $.ajax()//.ts

tsconfig.json

TypeScript: TSConfig Reference - Docs on every TSConfig option (typescriptlang.org)