TypeScript 是一種現代程式語言,由於其附加的型別安全性,通常比 JavaScript 更受青睞。在本文中,我將分享 10 個最重要的 TypeScript 概念,這將有助於提升您的 TypeScript 程式設計技能。準備好了嗎?開始吧。
1.泛型:使用泛型我們可以建立可重複使用的類型,這將有助於處理今天和明天的資料。
泛型範例:
我們可能想要 Typescript 中的一個函數將參數作為某種類型,並且我們可能想要傳回相同的類型。
function func<t>(args:T):T{ return args; } </t>
2.具有型別約束的泛型:現在讓我們透過定義它只接受字串和整數來限制型別 T:
function func<t extends string number>(value: T): T { return value; } const stringValue = func("Hello"); // Works, T is string const numberValue = func(42); // Works, T is number // const booleanValue = func(true); // Error: Type 'boolean' is not assignable to type 'string | number' </t>
3.通用介面:
當您想要為使用各種類型的物件、類別或函數定義契約(形狀)時,介面泛型非常有用。它們允許您定義一個藍圖,該藍圖可以適應不同的資料類型,同時保持結構一致。
// Generic interface with type parameters T and U interface Repository<t u> { items: T[]; // Array of items of type T add(item: T): void; // Function to add an item of type T getById(id: U): T | undefined; // Function to get an item by ID of type U } // Implementing the Repository interface for a User entity interface User { id: number; name: string; } class UserRepository implements Repository<user number> { items: User[] = []; add(item: User): void { this.items.push(item); } getById(idOrName: number | string): User | undefined { if (typeof idOrName === 'string') { // Search by name if idOrName is a string console.log('Searching by name:', idOrName); return this.items.find(user => user.name === idOrName); } else if (typeof idOrName === 'number') { // Search by id if idOrName is a number console.log('Searching by id:', idOrName); return this.items.find(user => user.id === idOrName); } return undefined; // Return undefined if no match found } } // Usage const userRepo = new UserRepository(); userRepo.add({ id: 1, name: "Alice" }); userRepo.add({ id: 2, name: "Bob" }); const user1 = userRepo.getById(1); const user2 = userRepo.getById("Bob"); console.log(user1); // Output: { id: 1, name: "Alice" } console.log(user2); // Output: { id: 2, name: "Bob" } </user></t>
4.泛型類別::當您希望類別中的所有屬性都遵循泛型參數指定的類型時,請使用此選項。這允許靈活性,同時確保類別的每個屬性都與傳遞給類別的類型相符。
interface User { id: number; name: string; age: number; } class UserDetails<t extends user> { id: T['id']; name: T['name']; age: T['age']; constructor(user: T) { this.id = user.id; this.name = user.name; this.age = user.age; } // Method to get user details getUserDetails(): string { return `User: ${this.name}, ID: ${this.id}, Age: ${this.age}`; } // Method to update user name updateName(newName: string): void { this.name = newName; } // Method to update user age updateAge(newAge: number): void { this.age = newAge; } } // Using the UserDetails class with a User type const user: User = { id: 1, name: "Alice", age: 30 }; const userDetails = new UserDetails(user); console.log(userDetails.getUserDetails()); // Output: "User: Alice, ID: 1, Age: 30" // Updating user details userDetails.updateName("Bob"); userDetails.updateAge(35); console.log(userDetails.getUserDetails()); // Output: "User: Bob, ID: 1, Age: 35" console.log(new UserDetails("30")); // Error: "This will throw error" </t>
5.將型別參數約束為傳遞的型別:有時,我們希望參數型別依賴其他一些傳遞的參數。聽起來很混亂,讓我們看下面的範例。
function getProperty<type>(obj: Type, key: keyof Type) { return obj[key]; } let x = { a: 1, b: 2, c: 3 }; getProperty(x, "a"); // Valid getProperty(x, "d"); // Error: Argument of type '"d"' is not assignable to parameter of type '"a" | "b" | "c"'. </type>
6.條件類型:通常,我們希望我們的類型是一種類型或另一種類型。在這種情況下,我們使用條件類型。
一個簡單的例子是:
function func(param:number|boolean){ return param; } console.log(func(2)) //Output: 2 will be printed console.log(func("True")) //Error: boolean cannot be passed as argument
有點複雜的例子:
type HasProperty<t k extends keyof t> = K extends "age" ? "Has Age" : "Has Name"; interface User { name: string; age: number; } let test1: HasProperty<user>; // "Has Age" let test2: HasProperty<user>; // "Has Name" let test3: HasProperty<user>; // Error: Type '"email"' is not assignable to parameter of type '"age" | "name"'. </user></user></user></t>
6.交集類型:當我們想要將多種類型合併為一個類型時,這些類型非常有用,允許特定類型繼承各種其他類型的屬性和行為。
讓我們來看一個有趣的例子:
// Defining the types for each area of well-being interface MentalWellness { mindfulnessPractice: boolean; stressLevel: number; // Scale of 1 to 10 } interface PhysicalWellness { exerciseFrequency: string; // e.g., "daily", "weekly" sleepDuration: number; // in hours } interface Productivity { tasksCompleted: number; focusLevel: number; // Scale of 1 to 10 } // Combining all three areas into a single type using intersection types type HealthyBody = MentalWellness & PhysicalWellness & Productivity; // Example of a person with a balanced healthy body const person: HealthyBody = { mindfulnessPractice: true, stressLevel: 4, exerciseFrequency: "daily", sleepDuration: 7, tasksCompleted: 15, focusLevel: 8 }; // Displaying the information console.log(person);
7.infer 關鍵字:當我們想要有條件地確定特定類型時,infer 關鍵字很有用,並且當滿足條件時,它允許我們從該類型中提取子類型。
這是一般語法:
type ConditionalType<t> = T extends SomeType ? InferredType : OtherType; </t>
範例:
type ReturnTypeOfPromise<t> = T extends Promise<infer u> ? U : number; type Result = ReturnTypeOfPromise<promise>>; // Result is 'string' type ErrorResult = ReturnTypeOfPromise<number>; // ErrorResult is 'never' const result: Result = "Hello"; console.log(typeof result); // Output: 'string' </number></promise></infer></t>
8.Type Variance:這個概念討論了子類型和父類型如何相互關聯。
它們有兩種類型:
協方差:可以在需要父類型的地方使用子類型。
讓我們來看一個例子:
function func<t>(args:T):T{ return args; } </t>
在上面的範例中,Car 繼承了 Vehicle 類別的屬性,因此將其指派給需要超類型的子類型是絕對有效的,因為子類型將具有超類型所具有的所有屬性。
逆變:這與協變相反。我們在子類型應該出現的地方使用超類型。
function func<t extends string number>(value: T): T { return value; } const stringValue = func("Hello"); // Works, T is string const numberValue = func(42); // Works, T is number // const booleanValue = func(true); // Error: Type 'boolean' is not assignable to type 'string | number' </t>
使用逆變時,我們需要小心不要存取特定於子類型的屬性或方法,因為這可能會導致錯誤。
9。反思: 這個概念涉及在運行時確定變數的類型。雖然 TypeScript 主要專注於編譯時的類型檢查,但我們仍然可以利用 TypeScript 運算子在執行時檢查類型。
typeof 運算子:我們可以利用 typeof 運算子在執行時尋找變數的型別
// Generic interface with type parameters T and U interface Repository<t u> { items: T[]; // Array of items of type T add(item: T): void; // Function to add an item of type T getById(id: U): T | undefined; // Function to get an item by ID of type U } // Implementing the Repository interface for a User entity interface User { id: number; name: string; } class UserRepository implements Repository<user number> { items: User[] = []; add(item: User): void { this.items.push(item); } getById(idOrName: number | string): User | undefined { if (typeof idOrName === 'string') { // Search by name if idOrName is a string console.log('Searching by name:', idOrName); return this.items.find(user => user.name === idOrName); } else if (typeof idOrName === 'number') { // Search by id if idOrName is a number console.log('Searching by id:', idOrName); return this.items.find(user => user.id === idOrName); } return undefined; // Return undefined if no match found } } // Usage const userRepo = new UserRepository(); userRepo.add({ id: 1, name: "Alice" }); userRepo.add({ id: 2, name: "Bob" }); const user1 = userRepo.getById(1); const user2 = userRepo.getById("Bob"); console.log(user1); // Output: { id: 1, name: "Alice" } console.log(user2); // Output: { id: 2, name: "Bob" } </user></t>
instanceof 運算子:instanceof 運算子可用於檢查物件是否為類別或特定類型的實例。
interface User { id: number; name: string; age: number; } class UserDetails<t extends user> { id: T['id']; name: T['name']; age: T['age']; constructor(user: T) { this.id = user.id; this.name = user.name; this.age = user.age; } // Method to get user details getUserDetails(): string { return `User: ${this.name}, ID: ${this.id}, Age: ${this.age}`; } // Method to update user name updateName(newName: string): void { this.name = newName; } // Method to update user age updateAge(newAge: number): void { this.age = newAge; } } // Using the UserDetails class with a User type const user: User = { id: 1, name: "Alice", age: 30 }; const userDetails = new UserDetails(user); console.log(userDetails.getUserDetails()); // Output: "User: Alice, ID: 1, Age: 30" // Updating user details userDetails.updateName("Bob"); userDetails.updateAge(35); console.log(userDetails.getUserDetails()); // Output: "User: Bob, ID: 1, Age: 35" console.log(new UserDetails("30")); // Error: "This will throw error" </t>
我們可以使用第三方函式庫在執行時確定類型。
10.依賴注入:依賴注入是一種模式,允許您將程式碼引入元件中,而無需在元件中實際建立或管理它。雖然它看起來像是使用庫,但它有所不同,因為您不需要透過 CDN 或 API 安裝或匯入它。
乍一看,它似乎也類似於使用函數來實現可重複使用性,因為兩者都允許程式碼重複使用。然而,如果我們直接在組件中使用函數,可能會導致它們之間的緊密耦合。這意味著函數或其邏輯的任何變化都可能影響它使用的每個地方。
依賴注入透過將依賴項的建立與使用它們的元件解耦來解決這個問題,使程式碼更易於維護和測試。
沒有依賴注入的範例
function getProperty<type>(obj: Type, key: keyof Type) { return obj[key]; } let x = { a: 1, b: 2, c: 3 }; getProperty(x, "a"); // Valid getProperty(x, "d"); // Error: Argument of type '"d"' is not assignable to parameter of type '"a" | "b" | "c"'. </type>
依賴注入範例
function func(param:number|boolean){ return param; } console.log(func(2)) //Output: 2 will be printed console.log(func("True")) //Error: boolean cannot be passed as argument
在緊密耦合的場景中,如果您今天 MentalWellness 類別中有一個stressLevel 屬性,並決定明天將其更改為其他屬性,則需要更新所有使用它的地方。這可能會導致許多重構和維護挑戰。
但是,透過依賴注入和介面的使用,你可以避免這個問題。透過建構函式傳遞依賴項(例如 MentalWellness 服務),具體的實作細節(例如stressLevel 屬性)被抽像到介面後面。這意味著只要介面保持不變,對屬性或類別的變更不需要修改依賴類別。這種方法可確保程式碼鬆散耦合、更易於維護且更易於測試,因為您可以在運行時注入所需的內容,而無需緊密耦合元件。
以上是每個開發人員都應該了解的高級打字稿概念的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Python和JavaScript的主要區別在於類型系統和應用場景。 1.Python使用動態類型,適合科學計算和數據分析。 2.JavaScript採用弱類型,廣泛用於前端和全棧開發。兩者在異步編程和性能優化上各有優勢,選擇時應根據項目需求決定。

選擇Python還是JavaScript取決於項目類型:1)數據科學和自動化任務選擇Python;2)前端和全棧開發選擇JavaScript。 Python因其在數據處理和自動化方面的強大庫而備受青睞,而JavaScript則因其在網頁交互和全棧開發中的優勢而不可或缺。

Python和JavaScript各有優勢,選擇取決於項目需求和個人偏好。 1.Python易學,語法簡潔,適用於數據科學和後端開發,但執行速度較慢。 2.JavaScript在前端開發中無處不在,異步編程能力強,Node.js使其適用於全棧開發,但語法可能複雜且易出錯。

javascriptisnotbuiltoncorc; sanInterpretedlanguagethatrunsonenginesoftenwritteninc.1)JavascriptwasdesignedAsignedAsalightWeight,drackendedlanguageforwebbrowsers.2)Enginesevolvedfromsimpleterterpretpretpretpretpreterterpretpretpretpretpretpretpretpretpretcompilerers,典型地,替代品。

JavaScript可用於前端和後端開發。前端通過DOM操作增強用戶體驗,後端通過Node.js處理服務器任務。 1.前端示例:改變網頁文本內容。 2.後端示例:創建Node.js服務器。

選擇Python還是JavaScript應基於職業發展、學習曲線和生態系統:1)職業發展:Python適合數據科學和後端開發,JavaScript適合前端和全棧開發。 2)學習曲線:Python語法簡潔,適合初學者;JavaScript語法靈活。 3)生態系統:Python有豐富的科學計算庫,JavaScript有強大的前端框架。

JavaScript框架的強大之處在於簡化開發、提升用戶體驗和應用性能。選擇框架時應考慮:1.項目規模和復雜度,2.團隊經驗,3.生態系統和社區支持。

引言我知道你可能會覺得奇怪,JavaScript、C 和瀏覽器之間到底有什麼關係?它們之間看似毫無關聯,但實際上,它們在現代網絡開發中扮演著非常重要的角色。今天我們就來深入探討一下這三者之間的緊密聯繫。通過這篇文章,你將了解到JavaScript如何在瀏覽器中運行,C 在瀏覽器引擎中的作用,以及它們如何共同推動網頁的渲染和交互。 JavaScript與瀏覽器的關係我們都知道,JavaScript是前端開發的核心語言,它直接在瀏覽器中運行,讓網頁變得生動有趣。你是否曾經想過,為什麼JavaScr


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver Mac版
視覺化網頁開發工具

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3漢化版
中文版,非常好用

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!