你好,你好! ! :D
希望你們一切都好!
我們的真實感受:
我帶著本系列的第二部分回來了。 ?
在本章中,我們將深入探討我在面試過程中遇到的✨Typescript✨問題。
我的介紹會很簡短,所以讓我們直接開始吧!
## 問題
1. Typescript 中的泛型是什麼?
2. 介面和類型有什麼差別?
3.any、null、unknown、never有什麼差別?
簡短的答案是...
TypeScript 中的泛型允許我們建立可重複使用的函數、類別和接口,這些函數、類別和介面可以與多種類型一起使用,而無需指定特定類型。這有助於避免使用 any 作為包羅萬象的類型。
語法
;用於宣告泛型類型,但您也可以使用 、 或任何其他佔位符。
它是如何運作的?
讓我們用一個例子來分解它。
假設我有一個函數,它接受一個參數並傳回一個相同類型的元素。如果我用特定類型編寫函數,它將如下所示:
function returnElement(element: string): string { return element; } const stringData = returnElement("Hello world");
我知道 stringData 的類型將是“string”,因為我聲明了它。
但是如果我想回傳不同的類型會怎麼樣?
const numberData = returnElement(5);
我將收到一條錯誤訊息,因為類型與聲明的類型不同。
解決方案可能是建立一個新函數來傳回數字類型。
function returnNumber(element: number): number { return element; }
這種方法可行,但可能會導致重複的程式碼。
避免這種情況的一個常見錯誤是使用 any 而不是聲明的類型,但這違背了類型安全的目的。
function returnElement2(element: any): any { return element; }
但是,使用 any 會導致我們失去 Typescript 所具有的類型安全性和錯誤偵測功能。
另外,如果您在需要避免重複程式碼時就開始使用any,您的程式碼將失去可維護性。
這正是使用泛型有益的時候。
function returnGenericElement<T>(element: T): T { return element; }
函數將接收特定類型的元素;該類型將取代泛型並在整個運行時保持不變。
這種方法使我們能夠消除重複的程式碼,同時保持類型安全。
function returnElement(element: string): string { return element; } const stringData = returnElement("Hello world");
但是如果我需要來自陣列的特定函數怎麼辦?
我們可以將泛型宣告為陣列並這樣寫:
const numberData = returnElement(5);
那麼,
function returnNumber(element: number): number { return element; }
聲明的類型將替換為作為參數提供的類型。
我們也可以在類別中使用泛型。
function returnElement2(element: any): any { return element; }
我有三點要說關於這段程式碼:
它的外觀如下:
function returnGenericElement<T>(element: T): T { return element; }
並且,在結束這個問題之前要補充的最後一件事。
請記住,泛型是 Typescript 的一個功能。這意味著當我們將其編譯為 Javascript 時,泛型將被刪除。
來自
const stringData2 = returnGenericElement("Hello world"); const numberData2 = returnGenericElement(5);
到
function returnLength<T>(element: T[]): number { return element.length; }
簡短的答案是:
- 聲明合併適用於接口,但不適用於型別。
- 您不能在具有聯合類型的類別中使用實作。
- 您不能將擴充功能與使用聯合類型的介面一起使用。
關於第一點,聲明合併是什麼意思?
讓我告訴你:
我在類別中使用同一個介面時定義了兩次。然後,該類別將合併兩個定義中聲明的屬性。
const stringLength = returnLength(["Hello", "world"]);
類型不會發生這種情況。如果我們嘗試多次定義一個類型,TypeScript 將會拋出錯誤。
class Addition<U> { add: (x: U, y: U) => U; }
關於以下幾點,我們來區分並集和交集類型:
聯合類型允許我們指定一個值可以是多種類型之一。當一個變數可以保存多種類型時,這非常有用。
交叉類型允許我們將類型組合為一個。它是使用 & 運算子定義的。
const operation = new Addition<number>(); operation.add = (x, y) => x + y; => We implement the function here console.log(operation.add(5, 6)); // 11
聯合類型:
function returnGenericElement<T>(element: T): T { return element; }
交叉口類型:
function returnElement(element: string): string { return element; } const stringData = returnElement("Hello world");
如果我們嘗試將 Implements 關鍵字與聯合類型(例如 Animal)一起使用,TypeScript 將拋出錯誤。這是因為 Implements 需要單一介面或類型,而不是聯合類型。
const numberData = returnElement(5);
Typescript 允許我們使用「工具」:
a.交叉口型
function returnNumber(element: number): number { return element; }
b.介面
function returnElement2(element: any): any { return element; }
function returnGenericElement<T>(element: T): T { return element; }
c.單一型。
const stringData2 = returnGenericElement("Hello world"); const numberData2 = returnGenericElement(5);
當我們嘗試將擴充功能與聯合型別一起使用時,也會出現相同的問題。 TypeScript 將拋出錯誤,因為介面無法擴充聯合類型。這是一個例子
function returnLength<T>(element: T[]): number { return element.length; }
你不能擴展聯合類型,因為它代表多種可能的類型,並且不清楚應該繼承哪個類型的屬性。
但是你可以擴充類型或介面。
const stringLength = returnLength(["Hello", "world"]);
此外,您可以擴充單一類型。
class Addition<U> { add: (x: U, y: U) => U; }
簡短回答:
任意=>它是一個頂層類型變數(也稱為通用型別或通用超型別)。 當我們在變數中使用any時,該變數可以保存任何類型。它通常在變數的特定類型未知或預期會更改時使用。然而,使用any 並不被認為是最佳實踐;建議使用泛型代替。
const operation = new Addition<number>(); operation.add = (x, y) => x + y; => We implement the function here console.log(operation.add(5, 6)); // 11
雖然any允許呼叫方法之類的操作,但TypeScript編譯器在此階段不會捕獲錯誤。例如:
function returnGenericElement<T>(element: T): T { return element; }
您可以將任何值指派給任何變數:
function returnGenericElement(element) { return element; }
此外,您可以將任何變數指派給另一個具有定義類型的變數:
interface CatInterface { name: string; age: number; } interface CatInterface { color: string; } const cat: CatInterface = { name: "Tom", age: 5, color: "Black", };
未知 =>這種類型與任何類型一樣,可以保存任何值,也被認為是頂級類型。當我們不知道變數類型時,我們會使用它,但稍後會對其進行賦值,並在運行時保持不變。未知是比任何類型都更不寬容的類型。
type dog = { name: string; age: number; }; type dog = { // Duplicate identifier 'dog'.ts(2300) color: string; }; const dog1: dog = { name: "Tom", age: 5, color: "Black", //Object literal may only specify known properties, and 'color' does not exist in type 'dog'.ts(2353) };
直接呼叫未知的方法將導致編譯時錯誤:
type cat = { name: string; age: number; }; type dog = { name: string; age: number; breed: string; };
在使用它之前,我們應該執行以下檢查:
type animal = cat | dog;
與任何類型一樣,我們可以為變數分配任何類型。
type intersectionAnimal = cat & dog;
但是,我們不能將未知類型指派給其他類型,只能將 any 或unknown 指派給其他類型。
function returnElement(element: string): string { return element; } const stringData = returnElement("Hello world");
這將向我們顯示一個錯誤
空=>變數可以保存任一型別。這意味著該變數沒有值。
const numberData = returnElement(5);
嘗試將任何其他類型指派給空變數將導致錯誤:
function returnNumber(element: number): number { return element; }
從不=>我們使用此類型來指定函數沒有傳回值。
function returnElement2(element: any): any { return element; }
我們以 Typescript 結束,
今天(?
我希望這對某人有幫助。
如果您有任何技術面試問題希望我解釋,請隨時在評論中告訴我。 ??
本週過得愉快嗎?
以上是技術面試問題 - 部分打字稿的詳細內容。更多資訊請關注PHP中文網其他相關文章!