久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合

站長資訊網
最全最豐富的資訊網站

了解TypeScript中泛型(Generics)的概念和用法

了解TypeScript中泛型(Generics)的概念和用法

本文介紹TypeScript中泛型(Generics)的概念和用法,它為什么重要,及其使用場景。我們會以一些清晰的例子,介紹其語法,類型和如何構建參數。你可以在你的集成開發環境中跟著實踐。

準備工作

要從本文中跟著學習的話,你需要在電腦上準備以下東西:

  • 安裝Node.js:你可以運行命令行檢查Node是否安裝好了。
node -v
  • 安裝Node Package Manager: 通常安裝Node時,它會順帶安裝好所需版本的NPM。
  • 安裝TypeScript:如果你安裝好了Node Package Manager,你可以用以下命令在本機的全局環境安裝TypeScript。
  • npm install -g typescript

    集成開發環境:本文將使用微軟團隊開發的Visual Studio Code。可以在這里下載。進入其下載的目錄,并按照提示進行安裝。記得選擇“添加打開代碼”(Add open with code)選項,這樣你就可以在本機從任何位置輕松打開VS Code了。

本文是寫給各層次的TypeScript開發人員的,包括但并不只是初學者。 這里給出了設置工作環境的步驟,是為了照顧那些TypeScript和Visual Studio Code的新手們。

TypeScript里的泛型是個啥

在TypeScript中,泛型是一種創建可復用代碼組件的工具。這種組件不只能被一種類型使用,而是能被多種類型復用。類似于參數的作用,泛型是一種用以增強類(classes)、類型(types)和接口(interfaces)能力的非常可靠的手段。這樣,我們開發者,就可以輕松地將那些可復用的代碼組件,適用于各種輸入。然而,不要把TypeScript中的泛型錯當成any類型來使用——你會在后面看到這兩者的不同。

類似C#和Java這種語言,在它們的工具箱里,泛型是創建可復用代碼組件的主要手段之一。即,用于創建一個適用于多種類型的代碼組件。這允許用戶以他們自己的類使用該泛型組件。

在VSCode中配置TypeScript

在計算機中創建一個新文件夾,然后使用VS Code 打開它(如果你跟著從頭開始操作,那你已經安裝好了)。

在VS Code中,創建一個app.ts文件。我的TypeScript代碼都會放在這里面。

把下面打日志的代碼拷貝到編輯器中:

console.log("hello TypeScript");

按下F5鍵,你會看到一個像這樣的launch.json文件:

{   // Use IntelliSense to learn about possible attributes.   // Hover to view descriptions of existing attributes.   // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387   "version": "0.2.0",   "configurations": [     {       "type": "node",       "request": "launch",       "name": "TypeScript",       "program": "${workspaceFolder}\app.ts",       "outFiles": [         "${workspaceFolder}/**/*.js"       ]     }   ] }

里面的name字段的值,本來是Launch Program,我把它改成了TypeScript。你可以把它改成其他值。

點擊Terminal Tab,選擇Run Tasks,再選擇一個Task Runner:"TypeScript Watch Mode",然后會彈出一個tasks.json文件,把它改成下面像這樣:

 {   // See https://go.microsoft.com/fwlink/?LinkId=733558   // for the documentation about the tasks.json format   "version": "2.0.0",   "tasks": [   {    "label": "echo",    "type": "shell",    "command": "tsc",    "args": ["-w", "-p","."],    "problemMatcher": [     "$tsc-watch"     ],    "isBackground": true    }   ]  }

app.ts所在的目錄,創建另一個文件tsconfig.json。把下面的代碼拷貝進去:

{   "compilerOptions": {     "sourceMap": true   } }

這樣,Task Runner就可以把TypeScript編譯成JavaScript,并且可監聽到文件的變化,實時編譯。

再次點擊Ternimal標簽,選擇Run Build Task,再選擇tsc: watch - tsconfig.json,可以看到終端出現的信息:

[21:41:31] Starting compilation in watch mode…

你可以使用VS Code的調試功能編譯TypeScript文件。  

了解TypeScript中泛型(Generics)的概念和用法

設置好了開發環境,你就可以著手處理TypeScript泛型概念相關的問題了。

找到問題

TypeScript中不建議使用any類型,原因有幾點,你可以在本文看到。其中一個原因,就是調試時缺乏完整的信息。而選擇VS Code作為開發工具的一個很好的理由,就是它帶來的基于這些信息的智能感知。

如果你有一個類,存儲著一個集合。有方法向該集合里添加東西,也有方法通過索引獲取集合里的東西。像這樣:

class Collection {   private _things: string[];   constructor() {     this._things = [];   }   add(something: string) {     this._things.push(something);   }   get(index: number): string {     return this._things[index];   } }

你可以很快辨識出,此集合被顯示定義為一個string類型的集合,顯然是不能在其中使用number的。如果想要處理number的話,可以創建一個接受number而不是string的集合。著是一個不錯的選擇,但有一個很大的缺點——代碼重復。代碼重復,最終會導致編寫和調試代碼的時間增多,并且降低內存的使用效率。

另一個選擇,是使用any類型代替string類型定義剛才的類,像下面這樣:

class Collection {   private _things: any[];   constructor() {     this._things = [];   }   add(something: any) {     this._things.push(something);   }   get(index: number): any {     return this._things[index];   } }

此時,該集合支持你給出的任何類型。如果你創建像這樣的邏輯構建此集合的話:

let Stringss = new Collection(); Stringss.add("hello"); Stringss.add("world");

這添加了字符串"hello"和"world"到集合中,你可以打出像length這樣的屬性,返回任意一個集合元素的長度。  

console.log(Stringss.get(0).length);

字符串"hello"有五個字符,運行TypeScript代碼,你可以在調試模式下看到它。  

了解TypeScript中泛型(Generics)的概念和用法

請注意,當你鼠標懸停在length屬性上時,VS Code的智能感知沒有提供任何信息,因為它不知道你選擇使用的確切類型。當你像下面這樣,把其中一個添加的元素修改為其他類型時,比如number,這種不能被智能感知到的情況會體現得更加明顯:

let Strings = new Collection(); Strings.add(001); Strings.add("world"); console.log(Strings.get(0).length);

你打出一個undefined的結果,仍然沒有什么有用信息。如果你更進一步,決定打印string的子字符串——它會報運行時錯誤,但不指不出任何具體的內容,更重要的是,編譯器沒有給出任何類型不匹配的編譯時錯誤。  

console.log(Stringss.get(0).substr(0,1));

了解TypeScript中泛型(Generics)的概念和用法

這僅僅是使用any類型定義該集合的一種后果罷了。

理解中心思想

剛才使用any類型導致的問題,可以用TypeScript中的泛型來解決。其中心思想是類型安全。使用泛型,你可以用一種編譯器能理解的,并且合乎我們判斷的方式,指定類、類型和接口的實例。正如在其他強類型語言中的情況一樣,用這種方法,就可以在編譯時發現你的類型錯誤,從而保證了類型安全。

泛型的語法像這樣:

function identity<T>(arg: T): T {   return arg; }

你可以在之前創建的集合中使用泛型,用尖括號括起來。  

class Collection<T> {   private _things: T[];   constructor() {     this._things = [];   }   add(something: T): void {     this._things.push(something);   }   get(index: number): T {     return this._things[index];   } } let Stringss = new Collection<String>(); Stringss.add(001); Stringss.add("world"); console.log(Stringss.get(0).substr(0, 1));

如果將帶有尖括號的新邏輯復制到代碼編輯器中,你會立即注意到"001"下的波浪線。這是因為,TypeScript現在可以從指定的泛型類型推斷出001不是字符串。在T出現的地方,就可以使用string類型,這就實現了類型安全。本質上,這個集合的輸出可以是任何類型,但你指明了它應該是string類型,所以編譯器推斷它就是string類型。這里使用的泛型聲明是在類級別,它也可以在其他級別定義,如靜態方法級別和實例方法級別,你稍后會看到。

使用泛型

你可以在泛型聲明中,包含多個類型參數,它們只需要用逗號分隔,像這樣:

class Collection<T, K> {   private _things: K[];   constructor() {     this._things = [];   }   add(something: K): void {     this._things.push(something);   }   get(index: number): T {     console.log(index);   } }

聲明時,類型參數也可以在函數中顯式使用,比如:

class Collection {   private _things: any[];   constructor() {     this._things = [];   }   add<A>(something: A): void {     this._things.push(something);   }   get<B>(index: number): B {     return this._things[index];   } }

因此,當你要創建一個新的集合時,在方法級別聲明的泛型,現在也會在方法調用級別中被指示,像這樣:  

let Stringss = new Collection(); Stringss.add<string>("hello"); Stringss.add("world");

你還可注意到,在鼠標懸停時,VS Code智能感知能夠推斷出第二個add函數調用仍然是string類型。

泛型聲明同樣適用于靜態方法:

static add<A>(something: A): void {   _things.push(something); }

雖然初始化靜態方法時,可使用泛型類型,但是,對初始化靜態屬性則不能。

泛型約束

現在,你已經對泛型有比較好的認識,是時候提到泛型的核心缺點及其實用的解決方案了。使用泛型,許多屬性的類型都能被TypeScript推斷出來,然而,在某些TypeScript不能做出準確推斷的地方,它不會做任何假設。為了類型安全,你需要將這些要求或者約束定義為接口,并在泛型初始化中繼承它們。

如果你有這樣一個非常簡單的函數:

function printName<T>(arg: T) {   console.log(arg.length);   return arg; } printName(3);

因為TypeScript無法推斷出arg參數是什么類型,不能證明所有類型都具有length屬性,因此不能假設它是一個字符串(具有length屬性)。所以,你會在length屬性下看到一條波浪線。如前所述,你需要創建一個接口,讓泛型的初始化可以繼承它,以便編譯器不再報警。  

interface NameArgs {   length: number; }

你可以在泛型聲明中繼承它:

function printName<T extends NameArgs>(arg: T) {   console.log(arg.length);   return arg; }

這告訴TypeScript,可使用任何具有length屬性的類型。 定義它之后,函數調用語句也必須更改,因為它不再適用于所有類型。 所以它應看起來是這樣:

printName({length: 1, value: 3});

這是一個很基礎的例子。但理解了它,你就能看到在使用泛型時,設置泛型約束是多么有用。

為什么是泛型

一個活躍于Stack Overflow社區的成員,Behrooz,在后續內容中很好的回答了這個問題。在TypeScript中使用泛型的主要原因是使類型,類或接口充當參數。 它幫助我們為不同類型的輸入重用相同的代碼,因為類型本身可用作參數。

泛型的一些好處有:

  • 定義輸入和輸出參數類型之間的關系。比如
function test<T>(input: T[]): T {   //…  }

允許你確保輸入和輸出使用相同的類型,盡管輸入是用的數組。

  • 可使用編譯時更強大的類型檢查。在上訴示例中,編譯器讓你知道數組方法可用于輸入,任何其他方法則不行。
  • 你可以去掉不需要的強制類型轉換。比如,如果你有一個常量列表:
Array<Item> a = [];

變量數組時,你可以由智能感知訪問到Item類型的所有成員。

其他資源

  • 官方文檔

結論

你已經看完了泛型概念的概述,并看到了各種示例來幫助揭示它背后的思想。 起初,泛型的概念可能令人困惑,我建議,把本文再讀一遍,并查閱本文所提供的額外資源,幫助自己更好地理解。泛型是一個很棒的概念,可以幫助我們在JavaScript中,更好地控制輸入和輸出。請快樂地編碼吧!

贊(0)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合
91精品一区二区三区综合| 欧美三级第一页| 欧美日韩一二| 欧美日韩激情在线一区二区三区| 免费欧美一区| 亚洲开心激情| 久久中文精品| 99久久精品费精品国产| 在线观看一区| 久草精品视频| 久久久人人人| 在线精品福利| 精品国产亚洲日本| 亚洲精品午夜av福利久久蜜桃| 中文精品在线| 国产日韩精品视频一区二区三区| 伊伊综合在线| 蜜桃视频第一区免费观看| 国产精品极品国产中出| 麻豆精品蜜桃| 日韩精品午夜视频| 国产videos久久| 精品91久久久久| 日本午夜精品| 久久精品影视| 欧美在线黄色| 久久亚洲精品中文字幕蜜潮电影| 日韩**一区毛片| 日韩不卡视频在线观看| 日av在线不卡| 国产在视频一区二区三区吞精| 欧美日韩国产精品一区二区亚洲| 日本v片在线高清不卡在线观看| 97精品国产| 亚洲精品免费观看| 国产精品国产一区| 亚洲精品国产精品粉嫩| 国产理论在线| 最新国产精品久久久| 亚洲一区区二区| 欧美国产小视频| 亚洲综合激情在线| 少妇久久久久| 麻豆久久久久久| 99成人在线| 久久国产免费看| 亚洲中午字幕| 欧美sm一区| 久久99精品久久久野外观看| 免费成人性网站| 99成人在线视频| 电影91久久久| 欧美日韩视频免费看| 午夜av一区| 电影91久久久| 国产精品一区免费在线| 久久国产高清| 高清av一区二区三区| 免费在线观看一区| 色综合视频一区二区三区日韩| 久久久久久久久久久妇女 | 91欧美精品| 亚洲激情黄色| 久久国产免费| 国产suv精品一区| 久久99影视| 国产精品毛片久久久| 亚洲精品亚洲人成在线观看| 欧美日韩国产高清电影| zzzwww在线看片免费| 国产剧情一区| 视频一区中文字幕精品| 亚洲专区一区| 天堂网在线观看国产精品| 成人午夜亚洲| 精品国产亚洲日本| 国产高清亚洲| 国产美女亚洲精品7777| 日韩精品三级| 日韩在线卡一卡二| aⅴ色国产欧美| 一区视频在线| 亚洲精品99| 尤物精品在线| 亚洲综合丁香| 午夜一级在线看亚洲| 99视频在线精品国自产拍免费观看| 日韩免费福利视频| 成人污污视频| 成人精品动漫一区二区三区| 精品色999| 福利一区视频| 天堂√中文最新版在线| 欧美男人天堂| 亚洲二区在线| 一区在线免费| 一区二区精彩视频| 日韩在线成人| 91福利精品在线观看| 日韩一区二区三区精品视频第3页| 一区二区国产在线| 亚洲免费观看高清完整版在线观| 亚洲涩涩av| 日韩高清成人在线| 久久狠狠久久| 精品一区二区三区亚洲| 麻豆理论在线观看| 午夜一级在线看亚洲| 日韩精品欧美成人高清一区二区| 91精品麻豆| 精品九九在线| 999精品在线| 日韩精品一级中文字幕精品视频免费观看| 亚洲人成高清| 国产精品草草| 日韩精品专区| 亚洲精品极品少妇16p| 男人的天堂久久精品| 日本亚洲三级在线| 久久精品国产在热久久| 免费污视频在线一区| 免播放器亚洲| 91国内精品| 不卡一二三区| 性色一区二区| 国产精品久久久网站| 中文字幕成在线观看| 精品一区欧美| 亚洲欧美专区| 久久麻豆视频| 99久久久久国产精品| 男女男精品网站| 久久99免费视频| 日韩欧美一区免费| 国产视频欧美| 国产精品日本一区二区三区在线 | 精品捆绑调教一区二区三区| 黄色av一区| 日韩一区二区三区免费播放| 每日更新成人在线视频| 欧美精品二区| 日韩av在线播放网址| 激情久久中文字幕| 麻豆成人在线| 另类综合日韩欧美亚洲| 久久国产电影| 中文字幕一区日韩精品| 国产精品白浆| 久久伦理在线| 日韩黄色在线观看| av中文字幕在线观看第一页| 黄色亚洲大片免费在线观看| 国产精品三级| 国产一级久久| 久久av中文| 另类亚洲自拍| 国产黄大片在线观看| 久色成人在线| 国产精品黑丝在线播放| 亚洲精品高潮| 日韩啪啪电影网| 午夜久久av| 日韩精品一区二区三区免费观看| 日韩手机在线| 久久国产免费| 国产精品18| 丝袜a∨在线一区二区三区不卡| 久久免费视频66| 免费中文字幕日韩欧美| 精品久久电影| 亚洲精品人人| 亚洲福利专区| 国产精品观看| 亚洲欧美日韩国产一区| 美女视频黄 久久| 免费日本视频一区| 日韩一二三区在线观看| 欧美日韩精品免费观看视欧美高清免费大片 | 夜夜嗨网站十八久久| 日韩av成人高清| 日韩欧美午夜| 国产高清日韩| 少妇精品久久久一区二区三区| 欧美经典一区| 免费看黄色91| 欧美色图一区| 福利一区二区| 国产精品成人自拍| 美日韩精品视频| 色在线中文字幕| 国产高清亚洲| 青青草精品视频| 久热re这里精品视频在线6| 日韩中文影院| 精品中文字幕一区二区三区四区| 亚洲精品少妇| 丝袜亚洲精品中文字幕一区| 99久久亚洲精品蜜臀| 国产在线观看www| 精品免费av一区二区三区|