iT邦幫忙

2023 iThome 鐵人賽

DAY 10
0
自我挑戰組

用ChatGPT詠唱來完成工作與點亮前後端技能樹系列 第 10

【Day10】ChatGPT請教教我:TypeScript!Enum!泛型 !

  • 分享至 

  • xImage
  •  

目前這個系列已挑選ChatGPT、前端&React相關章節出版成書!
感謝大家的閱讀與支持!
《用 ChatGPT 詠唱來點亮 React & 前端技能樹》
歷經重新整理、校正、編排、與修改後,讓章節內容之間的銜接更平順,除了補充上更多的解說之外,甚至有部分章節為重新撰寫的內容,讓理解變得更輕鬆!
目前已在天瓏書局博客來金石堂等通路都買得到了! 也有電子書的選擇!
歡迎各位點擊連結選購,謝謝大家~
https://ithelp.ithome.com.tw/upload/images/20240419/20135750lQM12by6v1.jpg


寫了一段時間的JavaScript,或多或少可能都有聽過TypeScript
TypeScript 是什麼呢?優點又是什麼呢?和JavaScript又有什麼不同?
直接來問問ChatGPT吧

初步認識TypeScript

https://ithelp.ithome.com.tw/upload/images/20230920/20135750qiKky6zkg1.png

對於一位初學者的前端工程師來說,了解 TypeScript 與 JavaScript 的差異是很重要的。

TypeScript 是一種由微軟開發的程式語言,它是 JavaScript 的超集合,這表示你可以在 TypeScript 中編寫符合 JavaScript 語法的程式碼。不過,TypeScript 提供了額外的功能,最主要的是型別系統。

型別系統可以讓你在程式碼中指定變數的型別,這樣可以在開發過程中提早發現潛在的錯誤,有助於提升程式碼的品質和可靠性。

相對於 JavaScript,TypeScript 在開發大型專案時更容易維護,因為它提供了更強大的程式碼靜態分析工具。

然而,初學者也許會發現 TypeScript 的學習曲線稍微陡峭,因為需要理解型別系統的概念。不過,一旦熟悉了這些概念,你會發現 TypeScript 可以幫助你更有效率地開發前端應用程式。

簡單來說,TypeScript 是 JavaScript 的擴充,提供了強大的型別系統,使得開發過程更加穩健和高效。

好像講了很多,但又有點沒解釋清楚
從上述可知,「TypeScript 是 JavaScript 的擴充」、「TypeScript引入了型別系統」

也就是JavaScript和 TypeScript的差別只差在「型別」
但是他又不講型別是什麼,所以只好來提問了
https://ithelp.ithome.com.tw/upload/images/20230920/201357504y6kcVsMxp.png

很好,你對於 TypeScript 的型別有興趣,這對於成為一名前端工程師來說是非常重要的一環。

TypeScript 的型別可以視為是一種對變數、函式參數、物件等進行約束的機制。透過型別,你可以告訴編譯器這些值的類型是什麼,這樣在開發過程中就能夠提前發現潛在的錯誤。

舉例來說,如果你宣告了一個變數 age,你可以使用型別來明確指定它是一個數字:

let age: number = 25;

這樣一來,如果你後續嘗試賦值一個字串給 age,TypeScript 的編譯器就會發出警告,提醒你這是一個型別不匹配的錯誤。

另一個好處是在函式參數的使用上。你可以明確指定參數的型別,這樣可以避免傳入錯誤型別的參數,提高程式碼的穩健性:

function greet(name: string) {
    return `Hello, ${name}!`;
}

在這個例子中,我們明確指定 name 參數的型別為字串。

總結來說,使用型別的好處包括:

  1. 提前發現錯誤:型別可以讓你在開發過程中發現並修復潛在的錯誤,這樣可以減少執行時期的錯誤。
  2. 提高程式碼可讀性:通過型別可以清楚地知道變數或函式的用途,讓程式碼更易於理解和維護。
  3. 提高協作效率:在團隊開發中,型別可以作為文件的一部分,讓其他開發者更容易理解你的程式碼。
  4. 增進開發工具的支援:現代的程式碼編輯器對於 TypeScript 提供了強大的支援,包括自動完成、錯誤提示等功能。

因此,學習如何有效地使用型別是成為一名優秀前端工程師的重要一步。

OK,上面簡易了示範了像是 let age: number = 25; 或是 name: string 這樣的語法

初步了解到「TypeScript 的型別可以視為是一種對變數、函式參數、物件等進行約束的機制」
指定了這個變數必須是數字,那麼他就必須是數字

接下來請他提供更多有關TypeScript的教學與語法

https://ithelp.ithome.com.tw/upload/images/20230920/20135750fomUlt5dh5.png

當然,我將詳細介紹 TypeScript,並提供一個簡單的 TypeScript 語法教學,以幫助你入門。首先,讓我們開始介紹 TypeScript 的基本特性。

TypeScript 簡介

TypeScript 是一種由微軟開發的程式語言,它是 JavaScript 的超集。這意味著你可以使用大部分 JavaScript 的語法,同時還能夠享受到 TypeScript 提供的額外功能,最主要的就是型別系統。

TypeScript 的優勢:

  1. 型別系統:TypeScript 允許你指定變數、函式參數、物件等的型別,有助於提前發現錯誤。
  2. 嚴格的編譯檢查:TypeScript 編譯器會在編譯時檢查代碼,並提供錯誤提示,幫助你減少執行時期的錯誤。
  3. 類型推斷:雖然你可以明確指定型別,但 TypeScript 也能根據上下文自動推斷型別,減少了繁瑣的型別聲明。
  4. 先進的編輯器支援:現代的程式碼編輯器(如 Visual Studio Code)對 TypeScript 提供了強大的支援,包括自動完成、重構、錯誤提示等功能。
  5. 大型專案的可維護性:TypeScript 特別適用於大型專案,它讓代碼更易於理解和維護。

現在,讓我們來看一些 TypeScript 的基本語法。

TypeScript 基本語法教學

1. 宣告變數

在 TypeScript 中,你可以使用 letconst 來宣告變數,並可以指定型別。

let age: number = 25;
const name: string = "John";

2. 函式宣告

你可以宣告函式,同樣可以指定參數和返回值的型別。

function add(x: number, y: number): number {
    return x + y;
}

3. 型別推斷

TypeScript 能夠自動推斷變數的型別,這減少了型別聲明的需求。

let num = 42; // TypeScript 推斷 num 為 number 型別

4. 介面(Interfaces)

介面可以用來定義物件的結構,這在與外部資料源互動時很有用。

interface Person {
    name: string;
    age: number;
}

let user: Person = {
    name: "Alice",
    age: 30,
};

5. 陣列和泛型

你可以宣告型別安全的陣列,也可以使用泛型。

let numbers: number[] = [1, 2, 3];
let names: Array<string> = ["Alice", "Bob"];

6. 判斷型別

你可以使用 typeofinstanceof 來判斷變數的型別。

let value: string | number;
if (typeof value === "string") {
    // 做字串處理
} else if (typeof value === "number") {
    // 做數字處理
}

這只是 TypeScript 的基本語法,還有更多進階的概念,如型別別名、列舉、類別等等。建議你先從這些基礎開始,然後逐漸深入學習,以成為一名熟練的前端工程師。希望這份簡單的介紹對你有所幫助!

看起來就是必須在變數要開始處理之前,就必須明訂他的型別(Type)是什麼

可以是數字(number)、字串(string)、甚至是物件

但上述只看到好像語法變麻煩了,實質好處是什麼似乎沒有舉例說明
因此我們請ChatGPT近一步說明

https://ithelp.ithome.com.tw/upload/images/20230920/201357500OJ2MWhjpc.png

當然,我會針對每個語法類型示範並解釋在沒有使用 TypeScript 時可能會遇到的問題,以及 TypeScript 如何解決或改善這些問題。

1. 宣告變數

JavaScript(沒有型別):

let age = 25;
age = "25"; // 沒有錯誤,但可能在執行時期產生錯誤

在 JavaScript 中,你可以將變數 age 重新賦值為字串,這在執行時期可能會導致錯誤。

TypeScript:

let age: number = 25;
age = "25"; // 錯誤:型別 'string' 的參數不能指派給型別 'number'

在 TypeScript 中,如果你嘗試將字串賦值給一個被指定為 number 型別的變數,TypeScript 編譯器會立即提出錯誤,幫助你在編譯時期發現這類錯誤。

2. 函式宣告

JavaScript:

function add(x, y) {
    return x + y;
}

add(5, "10"); // 不會產生錯誤,但可能在執行時期產生錯誤

在 JavaScript 中,你可以傳入任何型別的參數給 add 函式,這可能會導致在執行時期產生錯誤。

TypeScript:

function add(x: number, y: number): number {
    return x + y;
}

add(5, "10"); // 錯誤:引數的型別 '(number, string)' 與參數的型別 '(x: number, y: number) => number' 不相容

在 TypeScript 中,如果你嘗試傳入不正確型別的參數給 add 函式,TypeScript 編譯器會立即提出錯誤,讓你在編譯時期發現這類錯誤。

3. 型別推斷

JavaScript:

let num = 42;
num = "42"; // 沒有錯誤,但可能在執行時期產生錯誤

在 JavaScript 中,變數 num 的型別會在賦值時根據值的型別進行推斷。這可能會導致在執行時期產生錯誤。

TypeScript:

let num = 42;
num = "42"; // 錯誤:型別 'string' 的參數不能指派給型別 'number'

在 TypeScript 中,即使你沒有明確指定變數 num 的型別,TypeScript 也會根據賦值的值進行型別推斷。如果你嘗試賦值一個不相容的型別,TypeScript 會立即提出錯誤。

4. 介面(Interfaces)

JavaScript:

let user = {
    name: "Alice",
    age: 30,
    email: "alice@example.com"
};

在 JavaScript 中,你可以輕易地添加額外的屬性到物件中,這可能會導致在後續的代碼中產生錯誤。

TypeScript:

interface Person {
    name: string;
    age: number;
}

let user: Person = {
    name: "Alice",
    age: 30,
    email: "alice@example.com" // 錯誤:物件文字可以只指派已知屬性,但 'email' 屬性不存在於類型 'Person' 中
};

在 TypeScript 中,如果你嘗試添加未在介面中定義的屬性,TypeScript 會在編譯時期提出錯誤。

5. 陣列和泛型

JavaScript:

let numbers = [1, 2, 3];
numbers.push("4"); // 沒有錯誤,但可能在執行時期產生錯誤

在 JavaScript 中,你可以將不同型別的值添加到陣列中,這可能會導致在執行時期產生錯誤。

TypeScript:

let numbers: number[] = [1, 2, 3];
numbers.push("4"); // 錯誤:引數的型別 'string' 不可指派給型別 'number'

在 TypeScript 中,如果你嘗試將不相容的型別添加到陣列中,TypeScript 會在編譯時期提出錯誤。

總結:

TypeScript 通過強大的型別系統,提供了在編譯時期發現潛在錯誤的能力,從而增加了代碼的可靠性和可維護性。這些示範展示了在沒有 TypeScript 時可能發生的問題,以及 TypeScript 如何幫助你在開發過程中避免這些問題。透過 TypeScript,你可以開發出更加穩健和可靠的前端應用程式。

綜觀來說,TypeScript可以讓你在撰寫程式的時候,就先發現問題,就會先跑出錯誤
而不是程式上線運行之後,才發生諸如 5 + '10' = '510' 這種錯誤

有關型別的類型,上述看到了數字、字串、物件
我們接下來請他介紹TypeScript到底有哪些型別
https://ithelp.ithome.com.tw/upload/images/20230920/20135750Gq3NaQ8PqA.png

在 TypeScript 中,有多種型別供你使用。以下是一些常見的型別種類以及相應的範例:

  1. 基本型別 (Primitive Types)

    • number:表示數字。
    let age: number = 30;
    
    • string:表示字串。
    let name: string = "Alice";
    
    • boolean:表示布林值(true 或 false)。
    let isStudent: boolean = true;
    
    • nullundefined:表示空值或未定義的值。
    let emptyValue: null = null;
    let notDefined: undefined = undefined;
    
    • symbol:表示唯一的符號值(ES6 新增)。
    let uniqueSymbol: symbol = Symbol("unique");
    
  2. 陣列 (Array)

    • Array<型別>型別[]:表示一個具有相同型別元素的陣列。
    let numbers: number[] = [1, 2, 3];
    let names: Array<string> = ["Alice", "Bob"];
    
  3. 物件 (Object)

    • 使用介面(Interface)或類別(Class)來定義物件的結構。
    interface Person {
        name: string;
        age: number;
    }
    
    let user: Person = {
        name: "Alice",
        age: 30
    };
    
  4. 函式 (Function)

    • () => 型別:表示一個具有特定輸入和輸出型別的函式。
    let add: (x: number, y: number) => number = (x, y) => x + y;
    
  5. 元組 (Tuple)

    • 一個固定長度和特定型別的陣列。
    let person: [string, number] = ["Alice", 30];
    
  6. 列舉 (Enum)

    • 列舉一組具名的數值。
    enum Color {
        Red,
        Green,
        Blue
    }
    let favoriteColor: Color = Color.Blue;
    
  7. 聯合型別 (Union Types)

    • 使用 | 運算符表示多種可能的型別。
    let value: number | string = 42;
    value = "Hello";
    
  8. 交叉型別 (Intersection Types)

    • 使用 & 運算符結合多種型別。
    interface Person {
        name: string;
    }
    interface Employee {
        employeeId: number;
    }
    let worker: Person & Employee = { name: "Alice", employeeId: 123 };
    
  9. 任意型別 (Any)

    • any 型別表示可以是任何型別,通常用於舊有 JavaScript 代碼或不確定型別的情況,不建議使用。
    let unknownValue: any = 42;
    

這些是 TypeScript 中常見的型別種類,你可以根據不同的情況選擇適當的型別來聲明變數、函式參數等。型別系統有助於提高代碼的可靠性和可讀性。

學習了在TypeScript中的型別有哪些之後
可以注意到前面的講解中,有好幾個原本JavaScript中沒有出現過的關鍵字或名詞
像是 Enum、 Interfaces 、泛型

來逐一問看看ChatGPT

Enum (列舉)

https://ithelp.ithome.com.tw/upload/images/20230920/20135750nWgSB05t7x.png

當然可以!TypeScript 的 Enum(列舉)是一種用於定義具名數值的特殊型別,它為一系列相關的常數提供了一個名字。這使得程式碼更具可讀性,並且可以幫助避免使用難以理解的數字或字串。

以下是一些關於 TypeScript Enum 的教學和使用範例:

Enum 的定義

你可以使用 enum 關鍵字來定義一個 Enum:

enum Direction {
    Up,
    Down,
    Left,
    Right
}

在這個範例中,我們定義了一個名為 Direction 的 Enum,它包含了四個成員:UpDownLeftRight。這些成員的值將自動分配為從 0 開始的連續整數。

使用 Enum

你可以使用 Enum 成員的名字來引用它們:

let userDirection: Direction = Direction.Up;

這樣 userDirection 將被賦值為 Direction.Up,其對應的數值為 0。

Enum 的數字值

Enum 的成員默認是按照連續的整數值分配的,你也可以自定義成員的數值:

enum Color {
    Red = 1,
    Green = 2,
    Blue = 4
}

在這個範例中,Red 的值為 1,Green 的值為 2,Blue 的值為 4。

取得 Enum 成員的名字或數值

你可以使用 Enum 的名字或數值來取得相對應的成員:

let colorName: string = Color[2]; // 取得數值為 2 的成員名稱,此時 colorName 為 "Green"
let colorValue: number = Color.Blue; // 取得名稱為 "Blue" 的成員的數值,此時 colorValue 為 4

常見用法與優點

  1. 增強程式碼的可讀性:使用 Enum 可以讓程式碼更容易理解,因為你可以使用有意義的名字來表示數值的含義。
  2. 避免使用不清晰的數值:Enum 可以幫助你避免在程式碼中使用不清晰的數值,提高程式碼的可維護性。
  3. 節省記憶體空間:Enum 的成員在執行時期被視為常數,這意味著它們不會佔用額外的記憶體空間。
  4. 保護程式碼免於錯誤:使用 Enum 可以防止意外的賦值,因為只有 Enum 中定義的成員才能被使用。

總的來說,TypeScript 的 Enum 提供了一種有力的方式來管理具名的數值,使得程式碼更加清晰易讀且更容易維護。
https://ithelp.ithome.com.tw/upload/images/20230920/20135750BdGLRWLH9V.png

基本上我想講的差不多他都講了
我自己在開發上很常使用Enum,在一些固定的選項、設定值上,使用Enum能夠更容易維護

接下來我們來問問有關 Interfaces

Interface

https://ithelp.ithome.com.tw/upload/images/20230920/20135750oHv2zgm4zP.png

當談到 TypeScript 時,介面(Interfaces)是一個極為重要的概念,它用於定義物件的結構,以確保在程式碼中使用特定的屬性和方法。

以下是有關 TypeScript 的介面的介紹:

1. 介面的定義

在 TypeScript 中,你可以使用 interface 關鍵字來定義一個介面。介面描述了一個物件的形狀(屬性和方法)而不提供實際的實現。

interface Person {
    name: string;
    age: number;
}

在這個例子中,我們定義了一個名為 Person 的介面,它要求物件具有 name 屬性(字串型別)和 age 屬性(數字型別)。

2. 使用介面

一旦你定義了一個介面,你可以將它應用於物件,確保物件符合介面的結構。

let user: Person = {
    name: "Alice",
    age: 30
};

在這個範例中,我們創建了一個 user 物件,它符合 Person 介面的結構,即具有 nameage 屬性。

3. 選用屬性

你可以在介面中定義一些屬性為選用的,這表示物件可以包含或不包含這些屬性。使用 ? 符號來表示選用屬性。

interface Person {
    name: string;
    age?: number; // age 為選用屬性
}
let user1: Person = {
    name: "Alice"
};

let user2: Person = {
    name: "Bob",
    age: 25
};

在這個例子中,age 是選用屬性,所以你可以創建 user1 物件只包含 name,而 user2 物件包含 nameage

4. 函式型介面

你也可以使用介面來描述函式的形狀,這對於定義回呼函式非常有用。

interface Calculator {
    (x: number, y: number): number;
}
let add: Calculator = function(x, y) {
    return x + y;
};

let subtract: Calculator = function(x, y) {
    return x - y;
};

在這個例子中,我們定義了一個 Calculator 函式型介面,它要求函式接受兩個數字參數並返回一個數字。

5. 繼承介面

你可以使用 extends 關鍵字來繼承一個介面的結構,這使你可以構建更複雜的介面。

interface Person {
    name: string;
}

interface Employee extends Person {
    employeeId: number;
}

在這個範例中,Employee 介面繼承了 Person 介面的結構,所以它包含了 name 屬性並新增了 employeeId 屬性。

總結來說,TypeScript 的介面是一個強大的工具,用於定義物件的結構和形狀,以確保程式碼的型別安全性和可讀性。介面在開發大型應用程式和協作開發中非常有用,因為它提供了清晰的規範和約束。

也就是說,interface用於規範一個物件中的屬性或方法有哪些

但使用了一段時間typeScript的人就會知道
規範物件的屬性或方法,還有一個關鍵字叫做 type
同樣可以規範物件的型別

那麼interfacetype 的差異是什麼呢
https://ithelp.ithome.com.tw/upload/images/20230920/20135750w5PoY04EcQ.png

在 TypeScript 中,interfacetype 都是用來定義型別的方式,但它們有一些微妙的差異:

使用 Interface:

interface Person {
    name: string;
    age: number;
}

let user: Person = {
    name: "Alice",
    age: 30
};

使用 Type:

type Person = {
    name: string;
    age: number;
};

let user: Person = {
    name: "Alice",
    age: 30
};

主要差異:

  1. 語法差異

    • interface 關鍵字用於定義介面,它通常用於描述物件的結構。
    • type 關鍵字用於定義型別,它可以描述物件、函式、元組等型別。
  2. 擴展(extends)與聯合(union)型別

    • interface 可以透過 extends 關鍵字擴展其他介面,以合併屬性。
    • type 可以使用聯合(union)或交叉(intersection)型別來創建複雜的型別。
    type Dog = {
        name: string;
    }
    type Cat = {
        name: string;
    }
    
    type Pet = Dog | Cat; // Pet 可以是 Dog 或 Cat
    
    interface Dog {
        name: string;
    }
    
    interface Cat {
        name: string;
    }
    
    interface Pet extends Dog, Cat {} // Pet 同時擁有 Dog 和 Cat 的屬性
    
  3. 選用屬性(Optional Properties)

    • interface 中,你可以使用 ? 符號來定義選用屬性。
    • type 中,你可以使用 Partial<T> 泛型來使所有屬性變成選用。
    interface Person {
        name: string;
        age?: number; // age 為選用屬性
    }
    
    type PartialPerson = Partial<Person>; // 所有屬性變為選用
    
  4. 實現(Implements)與指派(Assignability)

    • interface 可以被類別(class)實現,這意味著類別需要符合介面的結構。
    • type 不能被類別實現。
    interface Printable {
        print: () => void;
    }
    
    class Book implements Printable {
        print() {
            console.log("Printing book...");
        }
    }
    

總的來說,interface 主要用於定義物件的結構,而 type 更靈活,可以用於定義任何型別,包括物件、函式、元組等等。在實際使用中,你可以根據需要選擇使用 interfacetype 來定義型別。通常來說,如果你需要擴展或實現一個類別,較常使用 interface。而如果你需要創建複雜的型別,較常使用 type

基本上語法差異以及擴充性的差異ChatGPT是講了
如果對兩者差異仍然有所困惑的,我個人也推這篇教學
Kira - 【Day 19】TypeScript 介面(Interface) v.s. 型別別名(Type Alias)

這裡面會講得更清楚,ChatGPT只會說依照開發風格跟需求決定
不過確實也是,用哪個其實都不算錯,只要有辦法規範出Type就行
我們繼續下個問題!

泛型

https://ithelp.ithome.com.tw/upload/images/20230920/201357500JowsZW6DA.png
我是貪婪的女人,把一堆問題擠在一起

以下是ChatGPT的介紹

泛型(Generics)是一種程式設計特性,它允許我們在定義函式、類別或介面時,能夠使用一個占位符(類似於變數)來代表不確定的型別。這樣可以使程式碼更具靈活性和重用性。

什麼時候會用到泛型?

  1. 函式需要在多種型別下工作

    泛型使得函式可以接受多種型別的參數,並返回相應的型別,從而提高了函式的通用性。

    function identity<T>(arg: T): T {
        return arg;
    }
    
    let result1 = identity(42); // result1 的型別為 number
    let result2 = identity("Hello"); // result2 的型別為 string
    
  2. 類別需要操作多種型別的屬性或方法

    泛型也可以應用於類別,以使其能夠操作多種型別的屬性或方法。

    class Box<T> {
        value: T;
        constructor(value: T) {
            this.value = value;
        }
    }
    
    let numberBox = new Box<number>(42);
    let stringBox = new Box<string>("Hello");
    
  3. 避免程式碼重複

    使用泛型可以減少冗餘的程式碼,因為你可以使用相同的程式邏輯來處理不同型別的數據。

    function firstElement<T>(arr: T[]): T {
        return arr[0];
    }
    
    let firstNum = firstElement([1, 2, 3]); // firstNum 的型別為 number
    let firstStr = firstElement(["a", "b", "c"]); // firstStr 的型別為 string
    

不使用泛型的缺點:

  1. 程式碼重複

    如果不使用泛型,你可能需要為每種型別編寫類似的程式碼,這會導致程式碼的重複和冗長。

    function firstElementNumber(arr: number[]): number {
        return arr[0];
    }
    
    function firstElementString(arr: string[]): string {
        return arr[0];
    }
    
  2. 型別不靈活

    不使用泛型會導致函式或類別僅能處理特定型別的數據,缺乏彈性。

    function firstElement(arr: number[]): number {
        return arr[0];
    }
    

總的來說,泛型使得程式碼更具彈性,可以應對不同型別的數據,同時也可以減少冗餘的程式碼,提高代碼的重用性和可讀性。在需要靈活應對多種型別的情況下,泛型是一個強大的工具。

綜合以上,TypeScript讓編寫程式的時候,必須嚴格遵守規定的type

一個函式的輸入必須是 string[] ,那麼就必定要是 string[] 才行
像上面的例子 firstElement()
目的只是挑出陣列的第一個元素,理論上只要輸入是陣列都可以套用這個function

在JS中確實是如此,JS中沒有限定類型,彈性最大,但也容易出現型別上的錯誤
TS因為需要事先限定類型,導致必須寫成兩個function,幾乎沒有彈性

因此,在TS中使用泛型,就能給予程式碼適當的彈性,在活用性與提供規範之間取得平衡

如何運行TypeScript的程式碼內容

如果是初次學習TypeScript的朋友,可能就會發現
如果副檔名使用.js,程式碼中使用 let name: string 時編譯器就會開始爆錯
但寫在一個.ts檔內,又沒辦法直接跟html使用

因此來問ChatGPT吧
https://ithelp.ithome.com.tw/upload/images/20230920/20135750xWBxoyTNlU.png

TypeScript 是一種超集合(Superset)的 JavaScript,這表示它包含了所有 JavaScript 的功能,同時還提供了一些額外的功能。但是,由於瀏覽器只能執行 JavaScript,所以在將 TypeScript 程式運行於瀏覽器之前,需要將其轉換為相應的 JavaScript。

以下是在 TypeScript 中開發並將程式運行在瀏覽器中的步驟:

步驟1:安裝 TypeScript 環境

首先,你需要在你的電腦上安裝 TypeScript 環境:

  1. 使用 npm 安裝 TypeScript:

    npm install -g typescript
    
  2. 確認 TypeScript 安裝成功:

    tsc -v
    

步驟2:開發 TypeScript 程式

創建一個 TypeScript 檔案(例如 app.ts)並開始編寫你的 TypeScript 程式碼。

function greet(name: string) {
    return `Hello, ${name}!`;
}

let message = greet("Alice");
console.log(message);

步驟3:編譯 TypeScript 程式

在終端機中,將 TypeScript 檔案編譯成 JavaScript:

tsc app.ts

這將會在相同的目錄下生成一個 app.js 檔案,它包含了編譯後的 JavaScript 代碼。

步驟4:建立 HTML 檔案

創建一個 HTML 檔案(例如 index.html)來載入你的 JavaScript 檔案。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My TypeScript App</title>
</head>
<body>
    <script src="app.js"></script>
</body>
</html>

步驟5:運行在瀏覽器中

將 HTML 檔案在瀏覽器中打開(雙擊即可),你將會在開發者工具的控制台中看到 Hello, Alice!

現在你已經成功地將 TypeScript 程式與 HTML 結合並在瀏覽器中運行了。如果你對 TypeScript 進行了更多的編輯,只需再次運行 tsc 命令以重新編譯即可。

也就是說,TypeScript其實瀏覽器沒有辦法閱讀和運行
如果要執行,就必須將其編譯成JavaScript,瀏覽器才看得懂

編譯這一步雖然很麻煩
但其實目前的網頁前後端框架,前端諸如React、Vue、Angular,後端像是Express、NestJS,這些都有支援TypeScript,在編譯打包或執行的時候,就能自動將TypeScript給進行轉換

所以未來要使用各大框架的時候,使用TypeScript一點都不麻煩

結語

JavaScript是一個弱型別的語言,並沒有強制規範型別,很容易要等到程式執行下去才發現錯誤
TypeScript有助於提早發現錯誤,且在維護上會更容易,更容易閱讀與理解
(真的不要太相信自己,在維護程式碼的時候常常會跟兩個月前的自己吵架)

完整的和ChatGPT的對話一樣放這裡:
https://chat.openai.com/share/4b2f4cfa-9e87-4e51-878c-88e4ae5a42af

另外,從之前介紹ES6語法的章節開始,到這個章節
都有提到 class (類別) 這個東西,也有提到一些「繼承」相關的概念
但我個人覺得要講class之前要先學type,所以遲遲還沒有介紹

有關class與物件導向,就留到下一篇學習!

我是與TypeScript相見恨晚的前端工程師一宵三筵,我們明天見~


上一篇
【Day9】ChatGPT請教教我:異步Promise、async/await、串接API
下一篇
【Day11】ChatGPT請教教我:Class(類別) ! Object (物件)!物件導向 OOP!
系列文
用ChatGPT詠唱來完成工作與點亮前後端技能樹56
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言