TS珠峰 001【學習筆記】

課程大綱

  • 建置 TypeScript 開發環境。
  • 掌握 TypeScript 的基礎類型、聯集類型和交集類型。
  • 詳細說明型別斷言的作用和用法。
  • 掌握 TypeScript 中函式、類別的型別宣告方式。
  • 掌握型別別名、介面的作用和定義。
  • 掌握泛型(Generics)的應用場景,熟練應用泛型。
  • 靈活運用條件類型、映射類型與內建類型。
  • 建立和使用自訂類型。
  • 理解命名空間(Namespace)、模組(Module)的概念及使用場景。
  • 詳細說明 TS 中的型別保護(Type Guard)、裝飾器(Decorator)。
  • 巧妙運用型別推導和簡化程式碼。
  • 深入理解 TypeScript 型別層級系統。
  • 詳細說明函式的變型(Variance)與逆變(Contravariance)。
  • 深入研究 infer 的用法與技巧。
  • 詳細探究符號類型。
  • 靈活編寫與運用型別宣告檔案,擴展 TypeScript 的型別系統。
  • 掌握 TS 中型別檔案查找規則。
  • 深刻使用裝飾器,運用反射元資料(Reflection Metadata)擴展裝飾器的功能,實現控制反轉(Inversion of Control, IoC)、依賴注入(Dependency Injection, DI)。
  • 深度解析 TSConfig 設定檔。
  • TS 型別體操

ts基礎

目前大部分企業的中大型前端專案都採用了 Typescript,那麼為什麼我們需要它?

JavaScript 的核心特點就是靈活,但隨著專案規模的增大,靈活反而增加開發者的心智負擔。例如在程式碼中一個變數可以被賦予字串、布林值、數字,甚至是函式,這樣就充滿了不確定性。而且這些不確定性可能需要在程式碼執行的時候才能被發現,所以我們需要型別的約束。

當然不可否認的是有了型別的加持多少會影響開發效率,但是可以讓大型專案更加健壯。

  • Typescript 更像後端 JAVA,讓 JS 可以開發大型企業應用;
  • TS 提供的型別系統可以幫助我們在撰寫程式碼時提供豐富的語法提示;
  • 在編寫程式碼時會對程式碼進行型別檢查,從而避免很多線上錯誤;

越來越多的專案開始擁抱 TS 了,典型的 Vue3、Pinia、第三方工具庫、後端 NodeJS 等。我們也經常為以上程式設計擁有更好的支援去編寫 .d.ts 檔案。

1. ts是一門語言

  1. ts 是 js 的一個超集,擴展了語法,添加了靜態型別支援以及其他一些新特性。

環境配置

全域安裝

npm install typescript -g
# 我們可以用 tsc 來把 ts 轉成 js
# 我們要把什麼轉換成什麼,所以我們要先生成一個設定
# 在目前專案下建立一個設定檔 tsc --init
# --watch
tsc --init
# 外掛程式 code runner 這個外掛程式需要額外安裝一個 ts-node 的套件
 npm init -y
 npm install typescript rollup -D
 npm install rollup-plugin-typescript -D
 npm i @rollup/plugin-node-resolve rollup-plugin-serve -D
#  rollup.config.js
# error lens 外掛程式

學習ts就是學習型別,ts的型別分類(DOM,Promise,原始方法)基礎類型,
ts 中:後面的都是型別 = 後面的都是值
ts 一切從安全的角度出發,看能不能賦值,就看安全不安全
ts 還有自動的型別推導,不用見到變數就寫型別,而是推斷的不正確,我們才需要自己編寫。

基礎類型

let abc: string = 'Hello World';
console.log(abc);

let name = 'John Doe'; // 目前模組中,作用域隔離
let age = 20;
let handsome: boolean = true;
// 原始類似識別碼都是小寫的,而類別名稱都是大寫的,它描述的實例(都是物件)
// 型別註解:告訴 TS 變數的型別
// 型別推斷:TS 會自動嘗試分析變數的型別
// 型別註解優先級高於型別推斷
// 型別註解:變數名: 型別 = 值
// 型別推斷:變數名 = 值
let s1: string = 'Hello World';
let s2: String = new String('Hello World');
let s3: String = 'Hello World'; // 會自動轉換為物件
// 陣列宣告
let arr1: number[] = [1, 2, 3];
let arr2: Array<number> = [1, 2, 3];
// 元組(Tuple):固定長度的陣列
let tuple: [string, number] = ['Hello', 123];
// 元組的越界問題
// tuple[2] = 'World'; // 會報錯
let tuple2: readonly [string, number, boolean] = ['Hello', 123, true];
// tuple2[0] = 'World'; // 會報錯
export { name };

列舉(自帶型別的物件)

let abc: string = 'Hello World';
console.log(abc);

let name = 'John Doe'; // 目前模組中,作用域隔離
let age = 20;
let handsome: boolean = true;
// 原始類似識別碼都是小寫的,而類別名稱都是大寫的,它描述的實例(都是物件)
// 型別註解:告訴 TS 變數的型別
// 型別推斷:TS 會自動嘗試分析變數的型別
// 型別註解優先級高於型別推斷
// 型別註解:變數名: 型別 = 值
// 型別推斷:變數名 = 值
let s1: string = 'Hello World';
let s2: String = new String('Hello World');
let s3: String = 'Hello World'; // 會自動轉換為物件
// 陣列宣告
let arr1: number[] = [1, 2, 3];
let arr2: Array<number> = [1, 2, 3];
// 元組:固定長度的陣列
let tuple: [string, number] = ['Hello', 123];
// 元組的越界問題
// tuple[2] = 'World'; // 會報錯
let tuple2: readonly [string, number, boolean] = ['Hello', 123, true];
// tuple2[0] = 'World'; // 會報錯

// 列舉(Enum) 自帶型別的物件,自動增長
enum USER_ROLE {
  USER,
  ADMIN = 6,
  MANAGER,
  OTHER = 'other', // 異構列舉
}
/*
  USER = 0,
  ADMIN = 6,
  MANAGER = 7,
*/
console.log(USER_ROLE.USER); // 0
// 如果不需要物件可以直接採用常數列舉
const enum USER_ROLE2 {
  USER,
  ADMIN,
  MANAGER,
}
console.log(USER_ROLE2.USER); // 0
export { name };

null 和 undefined

// 嚴格模式下,不允許使用 any 型別
// null 和 undefined 是任何型別的子型別
let x: number | null | undefined = 1;
// let y: number = undefined; // 會報錯
// let z: number = null; // 會報錯
// strict:false 可以使用 any 型別

never類型

永遠不

// never 型別 它是任何型別的子型別,也可以賦值給任何型別
// never 型別的變數只能被賦值為 never 型別
function fn1(): never {
  throw new Error('報錯了');
}
// 型別保護(Type Guard),保障程式的不缺失
// never 是永遠到達不了的終點
function fn2(): never {
  while (true) {}
}
function validate(x: never) {
  console.log(x);
}
// 針對不同的型別做不同的處理
function fn3(x: number | string | boolean) {
  // 類似有收斂的作用
  if (typeof x === 'number') {
    console.log(x.toFixed(2));
    return;
  }
  if (typeof x === 'string') {
    console.log(x.trim());
    return;
  }
  if (typeof x === 'boolean') {
    console.log(x.valueOf());
    return;
  }
  //守衛語句
  validate(x); // 如果型別不匹配,會報錯 這個邏輯應該是永遠不會執行的,所以上面還是有沒覆蓋到的邏輯(要添加 boolean 型別的判斷)
}

object的類型

// object 型別 object {} Object
let obj: object = { name: 'John Doe' };
// obj.name = 'Jane Doe'; // 會報錯
// 小寫的 object 是物件型別,大寫的 Object 是物件的建構函式 

! 號非空斷言

聯集類型

// 一般我們會基於額外的型別來擴展定義型別,有點類似列舉
type Direction = "up" | "down" | "right" | "left"
let direction :Direction = "left"
// type 和 interface 的區別
type women =
  | {
      wealthy: true;
      waste: string;
    }
  | {
      wealthy: false;
      norality: string;
    };
// 是富人一定不是節儉的人,是節儉的人一定不是富人

可以利用聯集類型來做到屬性之間的互斥

斷言

斷言有可能出問題,出問題後果自負

type women =
| {
wealthy: true;
waste: string;
}
| {
wealthy: false;
norality: string;
};
// 是富人一定不是節儉的人,是節儉的人一定不是富人(類比約定,不嚴謹)
// 斷言 把某個型別斷言為已經存在的一種型別
let ele = document.getElementById('app');
ele!.innerHTML = 'Hello World'; // 繞過 TS 的型別檢查 ele

主題測試文章,只做測試使用。發佈者:Walker,轉轉請注明出處:https://walker-learn.xyz/archives/4409

(0)
Walker的頭像Walker
上一篇 2026年3月10日 00:00
下一篇 2026年3月8日 15:40

相關推薦

  • 深入理解ES6 011【學習筆記】

    Promise與異步程式設計 因為執行引擎是單執行緒的,所以需要追蹤即將執行的程式碼,那些程式碼會被放在一個任務佇列中,每當一段程式碼準備執行時,都會被新增到任務佇列中,每當引擎中的一段程式碼結束執行時,事件迴圈會執行佇列中的下一個任務。 Promise 相當於異步操作結果的佔位符,它不會去訂閱一個事件,也不會傳遞一個回呼函式給目標函式,而是讓函式回傳一個 Promise,就像這樣…

    個人 2025年3月8日
    1.2K00
  • Go 工程師體系課 013【學習筆記】

    訂單事務 先扣庫存 後扣庫存 都會對庫存和訂單都會有影響,所以要使用分散式事務 業務(下單不對付)業務問題 支付成功再扣減(下單了,支付時沒庫存了) 訂單扣減,不支付(訂單超時歸還)【常用方式】 事務和分散式事務 1. 什麼是事務? 事務(Transaction)是資料庫管理系統中的一個重要概念,它是一組資料庫操作的集合,這些操作要麼全部成功執行,要麼全部…

    個人 2025年11月25日
    28500
  • 深入理解ES6 007【學習筆記】

    Set集合與Map集合 在js中有一個in運算子,其不需要讀取物件的值就能判斷屬性在物件中是否存在,如果存在就回傳true。但是in運算子也會檢查物件的原型,只有當物件原型為null時使用這個方法才比較穩妥。 Set集合 let set = new Set() set.add(5) set.add("5") console.log(s…

    個人 2025年3月8日
    1.3K00
  • TS珠峰 002【學習筆記】

    泛型 /* * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git &a…

    個人 2025年3月27日
    1.6K00
  • 熱愛運動,挑戰極限,擁抱自然

    熱愛 在這個快節奏的時代,我們被工作、生活的壓力所包圍,常常忽略了身體的需求。而運動,不只是一種健身方式,更是一種釋放自我、挑戰極限、與自然共舞的生活態度。無論是滑雪、攀岩、衝浪,還是跑步、騎行、瑜伽,每一種運動都能讓我們找到內心的激情,感受到生命的躍動。 運動是一場自我挑戰。挑戰極限,不只是職業運動員的專屬,而是每一個熱愛運動的人都可以追求的目標。它可…

    個人 2025年2月26日
    1.4K00