TypeScript(7)泛型

来源:https://www.cnblogs.com/jiakecong/archive/2022/06/22/16400029.html
-Advertisement-
Play Games

泛型 指在定義函數、介面或類的時候,不預先指定具體的類型,而在使用的時候再指定具體類型的一種特性。 引入 下麵創建一個函數, 實現功能: 根據指定的數量 count 和數據 value , 創建一個包含 count 個 value 的數組 不用泛型的話,這個函數可能是下麵這樣: function c ...


泛型

指在定義函數、介面或類的時候,不預先指定具體的類型,而在使用的時候再指定具體類型的一種特性。
 

引入

下麵創建一個函數, 實現功能: 根據指定的數量 count 和數據 value , 創建一個包含 countvalue 的數組 不用泛型的話,這個函數可能是下麵這樣:

function createArray(value: any, count: number): any[] {
    const arr: any[] = []
    for (let index=0; index < count; index++) {
        arr.push(value)
    }
    return arr
}

const arr1 = createArray('a', 3)
const arr2 = createArray(1, 3)
console.log(arr1)
console.log(arr2)
console.log(arr1[0].toFixed(), arr2[0].split(''))

我們創建了一個函數createArray,傳入2個參數valuecount,返回any類型的數組,然後定義了一個any類型的空數組arr。接下來我們查看結果

在編譯階段我們沒有報錯是因為,我們把value設置為了any類型,但是當編譯完成後運行時,arr1是字元串,字元串是沒有toFixed方法的,所以會報錯,那麼我們希望在編譯階段就報錯,就可以使用泛型
 

使用泛型

// 使用函數泛型
function createArray<T>(value: T, count: number): T[] {
    const arr: Array<T> = []
    for (let index=0; index < count; index++) {
        arr.push(value)
    }
    return arr
}
const arr1 = createArray<number>(11, 3)
console.log(arr1[0].toFixed())
const arr2 = createArray<string>('AA', 3)
console.log(arr2[0].split(''))
console.log('---------')
console.log(arr2[0].toFixed())  // 報錯,因為字元串沒有toFixed方法
console.log(arr1[0].split(''))  // 報錯,因為number沒有split方法

泛型的意思就是類型由用戶自己決定,比如function createArray<T>(value: T, count: number): T[],函數createArrayvalue參數和返回類型都由用戶自己決定。
const arr1 = createArray<number>(11, 3)這句代碼是沒問題,因為規定了number類型,傳入的也是number
 
當我們將代碼修改成如下代碼:

我們發現報錯了,因為規定了number類型,傳入的卻是字元串11

當我們輸入如下代碼,也會報錯

報錯原因如下

所以如果我們使用了泛型,就會避免類型輸入錯誤或者用錯方法
 

多個泛型參數的函數

一個函數可以定義多個泛型參數

function swap <K, V> (a: K, b: V): [K, V] {
  return [a, b]
}
const result = swap<string, number>('abc', 123)
console.log(result[0].length, result[1].toFixed())

 

泛型介面

interface IbaseCRUD <T> {
    // 定義泛型數組data
    data: T[]
    add: (t: T) => void
    getById: (id: number) => T
}

class User {
    id?: number;
    name: string;
    age: number;

    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
}

class UserCRUD implements IbaseCRUD<User> {
    data: User[] = []

    add(user: User): void {
        user = {...user, id: Date.now()}
        this.data.push(user)
        console.log('保存user', user.id)
    }

    getById(id: number): User {
        return this.data.find(item => item.id === id)
    }
}


const userCRUD = new UserCRUD()
userCRUD.add(new User('tom', 12))
userCRUD.add(new User('tom2', 13))
console.log(userCRUD.data)

 

泛型類

泛型類看上去與泛型介面差不多。 泛型類使用( <>)括起泛型類型,跟在類名後面。

class GenericNumber<T> {
    zeroValue: T;
    add: (x: T, y: T) => T;
}

let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };

GenericNumber類的使用是十分直觀的,並且你可能已經註意到了,沒有什麼去限制它只能使用number類型。 也可以使用字元串或其它更複雜的類型。

let stringNumeric = new GenericNumber<string>();
stringNumeric.zeroValue = "";
stringNumeric.add = function(x, y) { return x + y; };

console.log(stringNumeric.add(stringNumeric.zeroValue, "test"));

與介面一樣,直接把泛型類型放在類後面,可以幫助我們確認類的所有屬性都在使用相同的類型。
 

泛型約束

如果我們直接對一個泛型參數取 length 屬性, 會報錯, 因為這個泛型根本就不知道它有這個屬性

// 沒有泛型約束
function fn <T>(x: T): void {
  console.log(x.length)  // 報錯,因為目前不知道x是什麼類型
}

我們可以使用泛型約束來實現

interface Lengthwise {
  length: number;
}

// 指定泛型約束
function fn2 <T extends Lengthwise>(x: T): void {
  console.log(x.length)
}

我們需要傳入符合約束類型的值,必須包含必須 length 屬性:

fn2('abc')
// fn2(123) // error  number沒有length屬性

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • E-R圖也稱實體-聯繫圖(Entity Relationship Diagram),它提供了表示實體類型、屬性和聯繫的方法,用來描述現實世界的概念模型。 ...
  • 本文檔內容主要是分析android設備中cgroup v1實現了哪些控制器,他們有哪些子控制器以及如何配置這些控制器的。 我是使用紅米Note4Plus的開發版本來調研分析的,手機已經解鎖並具有了root許可權,可以隨意操作修改手機內容。不涉及到源代碼層面的調查分析。 設備的基本配置信息:高通msm8 ...
  • 開發者們,你希望用戶如何獲取新聞? 有的人靠手機彈窗知天下事,有的人則在新聞應用中盡覽每一篇文章;有的人一目十行,有的人則喜歡細細咀嚼;有的人主動探索,有的人則想要應用投其所好。 科技在不斷刷新著用戶獲取新聞的方式,與此同時,用戶自身也在發出新的獲知需求。HMS Core新聞行業解決方案,為新聞行業 ...
  • 今天繼續是對後臺管理部分的一個操作,但是快要結束了,今天結束,明天會進入一個從Vue以來,另外一個名聲顯著的東西了,一隻耳聞從未見識,而且十分的炫酷 他就是 數據可視化Echarts,迫不及待瞭解了 11.銷售屬性添加 當我們點擊添加就,應該把添加的放到table裡面來,table裡面每一行數據是一 ...
  • JavaScript 介紹 Javascript 語言誕生主要是完成頁面的數據驗證。因此它運行在客戶端,需要運行瀏覽器來解析執行 JavaScript 代碼。 JS 是 Netscape 網景公司的產品,最早取名為 LiveScript;為了吸引更多 java 程式員。更名為 JavaScript。 ...
  • watch是監聽某個變數或者屬性的變化,並執行相應的回調函數,通常是一個變數的變化決定多個變數的變化,watch可以進行非同步操作,但不支持緩存。一個偵聽器對應一條數據,當偵聽的數據發生變化是,watch才會執行對應的方法(一對一) computed計算屬性是依賴已有的變數來計算一個目標變數,大多數情 ...
  • 1、所謂數據響應式就是能夠使數據變化可以被檢測並對這種變化做出響應的機制。 2、MVVM框架要解決的一個核心問題是連接數據層和視圖層,通過數據驅動應用,數據變化,視圖更新,要做到這點的就需要對數據做響應式處理,這樣一旦數據發生變化就可以立即做出更新處理。 3、以vue為例說明,通過數據響應式加上虛擬 ...
  • 路由懶載入:有效拆分App尺寸,訪問時才非同步載入 keep-alive組件緩存:避免重覆創建組件實例,且能保留緩存組件狀態 使用v-show復用DOM:避免重覆創建組件 v-for遍歷避免同時使用v-if 長列表性能優化:如果是大數據長列表,可採用虛擬滾動(不會將所有內容渲染,只是把可是區域渲染), ...
一周排行
    -Advertisement-
    Play Games
  • 一:背景 準備開個系列來聊一下 PerfView 這款工具,熟悉我的朋友都知道我喜歡用 WinDbg,這東西雖然很牛,但也不是萬能的,也有一些場景他解決不了或者很難解決,這時候藉助一些其他的工具來輔助,是一個很不錯的主意。 很多朋友喜歡在項目中以記錄日誌的方式來監控項目的流轉情況,其實 CoreCL ...
  • 本來閑來無事,準備看看Dapper擴展的源碼學習學習其中的編程思想,同時整理一下自己代碼的單元測試,為以後的進一步改進打下基礎。 突然就發現問題了,源碼也不看了,開始改代碼,改了好久。 測試Dapper.LiteSql數據批量插入的時候,耗時20秒,感覺不正常,於是我測試了非Dapper版的Lite ...
  • 需求如下,在DEV框架項目中,需要在表格中增加一列顯示圖片,並且能編輯該列圖片,然後進行保存等操作,最終效果如下 這裡使用的是PictureEdit控制項來實現,打開DEV GridControl設計器,在ColumnEdit選擇PictureEdit: 綁定圖片代碼如下: DataTable dtO ...
  • 前兩天微軟偷偷更新了Visual Studio 2022 正式版版本 17.3 發佈,發佈摘要: MAUI 工作負荷 GA 生成 MAUI/Blazor CSS 熱重載支持 現在,你將能夠使用我們的新增功能在 Visual Studio 中使用每個更新試用一系列新功能。 選擇每個功能以瞭解有關特定功 ...
  • 航天和軍工領域的數字化轉型和建設正在積極推進,在與航天二院、航天三院、航天六院、航天九院、無線電廠、兵工廠等單位交流的過程中,用戶更聚焦試驗和生產過程中的痛點,迫切需要解決軟體平臺統一監測和控制設備及軟體與設備協同的問題。 ...
  • .NET 項目預設情況下 日誌是使用的 ILogger 介面,預設提供一下四種日誌記錄程式: 控制台 調試 EventSource EventLog 這四種記錄程式都是預設包含在 .NET 運行時庫中。關於這四種記錄程式的詳細介紹可以直接查看微軟的官方文檔 https://docs.microsof ...
  • 一:背景 上一篇我們聊到瞭如何去找 熱點函數,這一篇我們來看下當你的程式出現了 非托管記憶體泄漏 時如何去尋找可疑的代碼源頭,其實思路很簡單,就是在 HeapAlloc 或者 VirtualAlloc 時做 Hook 攔截,記錄它的調用棧以及分配的記憶體量, PerfView 會將這個 分配量 做成一個 ...
  • 背景 在 CI/CD 流程當中,測試是 CI 中很重要的部分。跟開發人員關係最大的就是單元測試,單元測試編寫完成之後,我們可以使用 IDE 或者 dot cover 等工具獲得單元測試對於業務代碼的覆蓋率。不過我們需要一個獨立的 CLI 工具,這樣我們才能夠在 Jenkins 的 CI 流程集成。 ...
  • 一、應用場景 大家在使用Mybatis進行開發的時候,經常會遇到一種情況:按照月份month將數據放在不同的表裡面,查詢數據的時候需要跟不同的月份month去查詢不同的表。 但是我們都知道,Mybatis是ORM持久層框架,即:實體關係映射,實體Object與資料庫表之間是存在一一對應的映射關係。比 ...
  • 我國目前並未出台專門針對網路爬蟲技術的法律規範,但在司法實踐中,相關判決已屢見不鮮,K 哥特設了“K哥爬蟲普法”專欄,本欄目通過對真實案例的分析,旨在提高廣大爬蟲工程師的法律意識,知曉如何合法合規利用爬蟲技術,警鐘長鳴,做一個守法、護法、有原則的技術人員。 案情介紹 深圳市快鴿互聯網科技有限公司 2 ...