亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

十分鐘教你理解TypeScript中的泛型

hosition / 1268人閱讀

摘要:進(jìn)入其下載的目錄,并按照提示進(jìn)行安裝。理解中心思想剛才使用類(lèi)型導(dǎo)致的問(wèn)題,可以用中的泛型來(lái)解決。你可以在泛型聲明中繼承它這告訴,可使用任何具有屬性的類(lèi)型。在中使用泛型的主要原因是使類(lèi)型,類(lèi)或接口充當(dāng)參數(shù)。

轉(zhuǎn)載請(qǐng)注明出處:葡萄城官網(wǎng),葡萄城為開(kāi)發(fā)者提供專(zhuān)業(yè)的開(kāi)發(fā)工具、解決方案和服務(wù),賦能開(kāi)發(fā)者。

你將在本文中學(xué)到什么

本文介紹TypeScript中泛型(Generics)的概念和用法,它為什么重要,及其使用場(chǎng)景。我們會(huì)以一些清晰的例子,介紹其語(yǔ)法,類(lèi)型和如何構(gòu)建參數(shù)。你可以在你的集成開(kāi)發(fā)環(huán)境中跟著實(shí)踐。

準(zhǔn)備工作

要從本文中跟著學(xué)習(xí)的話,你需要在電腦上準(zhǔn)備以下東西:

安裝Node.js:你可以運(yùn)行命令行檢查Node是否安裝好了。

node -v

安裝Node Package Manager: 通常安裝Node時(shí),它會(huì)順帶安裝好所需版本的NPM。
安裝TypeScript:如果你安裝好了Node Package Manager,你可以用以下命令在本機(jī)的全局環(huán)境安裝TypeScript。

npm install -g typescript

集成開(kāi)發(fā)環(huán)境:本文將使用微軟團(tuán)隊(duì)開(kāi)發(fā)的Visual Studio Code。可以在這里下載。進(jìn)入其下載的目錄,并按照提示進(jìn)行安裝。記得選擇“添加打開(kāi)代碼”(Add open with code)選項(xiàng),這樣你就可以在本機(jī)從任何位置輕松打開(kāi)VS Code了。
本文是寫(xiě)給各層次的TypeScript開(kāi)發(fā)人員的,包括但并不只是初學(xué)者。 這里給出了設(shè)置工作環(huán)境的步驟,是為了照顧那些TypeScript和Visual Studio Code的新手們。

TypeScript里的泛型是個(gè)啥

在TypeScript中,泛型是一種創(chuàng)建可復(fù)用代碼組件的工具。這種組件不只能被一種類(lèi)型使用,而是能被多種類(lèi)型復(fù)用。類(lèi)似于參數(shù)的作用,泛型是一種用以增強(qiáng)類(lèi)(classes)、類(lèi)型(types)和接口(interfaces)能力的非??煽康氖侄?。這樣,我們開(kāi)發(fā)者,就可以輕松地將那些可復(fù)用的代碼組件,適用于各種輸入。然而,不要把TypeScript中的泛型錯(cuò)當(dāng)成any類(lèi)型來(lái)使用——你會(huì)在后面看到這兩者的不同。

類(lèi)似C#和Java這種語(yǔ)言,在它們的工具箱里,泛型是創(chuàng)建可復(fù)用代碼組件的主要手段之一。即,用于創(chuàng)建一個(gè)適用于多種類(lèi)型的代碼組件。這允許用戶(hù)以他們自己的類(lèi)使用該泛型組件。

在VS Code中配置TypeScript

在計(jì)算機(jī)中創(chuàng)建一個(gè)新文件夾,然后使用VS Code 打開(kāi)它(如果你跟著從頭開(kāi)始操作,那你已經(jīng)安裝好了)。

在VS Code中,創(chuàng)建一個(gè)app.ts文件。我的TypeScript代碼都會(huì)放在這里面。

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

console.log("hello TypeScript");

按下F5鍵,你會(huì)看到一個(gè)像這樣的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字段的值,本來(lái)是Launch Program,我把它改成了TypeScript。你可以把它改成其他值。

點(diǎn)擊Terminal Tab,選擇Run Tasks,再選擇一個(gè)Task Runner:"TypeScript Watch Mode",然后會(huì)彈出一個(gè)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所在的目錄,創(chuàng)建另一個(gè)文件tsconfig.json。把下面的代碼拷貝進(jìn)去:

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

這樣,Task Runner就可以把TypeScript編譯成JavaScript,并且可監(jiān)聽(tīng)到文件的變化,實(shí)時(shí)編譯。

再次點(diǎn)擊Ternimal標(biāo)簽,選擇Run Build Task,再選擇tsc: watch - tsconfig.json,可以看到終端出現(xiàn)的信息:

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

你可以使用VS Code的調(diào)試功能編譯TypeScript文件。  

設(shè)置好了開(kāi)發(fā)環(huán)境,你就可以著手處理TypeScript泛型概念相關(guān)的問(wèn)題了。

找到問(wèn)題

TypeScript中不建議使用any類(lèi)型,原因有幾點(diǎn),你可以在本文看到。其中一個(gè)原因,就是調(diào)試時(shí)缺乏完整的信息。而選擇VS Code作為開(kāi)發(fā)工具的一個(gè)很好的理由,就是它帶來(lái)的基于這些信息的智能感知。

如果你有一個(gè)類(lèi),存儲(chǔ)著一個(gè)集合。有方法向該集合里添加?xùn)|西,也有方法通過(guò)索引獲取集合里的東西。像這樣:

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

你可以很快辨識(shí)出,此集合被顯示定義為一個(gè)string類(lèi)型的集合,顯然是不能在其中使用number的。如果想要處理number的話,可以創(chuàng)建一個(gè)接受number而不是string的集合。著是一個(gè)不錯(cuò)的選擇,但有一個(gè)很大的缺點(diǎn)——代碼重復(fù)。代碼重復(fù),最終會(huì)導(dǎo)致編寫(xiě)和調(diào)試代碼的時(shí)間增多,并且降低內(nèi)存的使用效率。

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

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

此時(shí),該集合支持你給出的任何類(lèi)型。如果你創(chuàng)建像這樣的邏輯構(gòu)建此集合的話:

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

這添加了字符串"hello"和"world"到集合中,你可以打出像length這樣的屬性,返回任意一個(gè)集合元素的長(zhǎng)度?! ?/p>

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

字符串"hello"有五個(gè)字符,運(yùn)行TypeScript代碼,你可以在調(diào)試模式下看到它?! ?/p>

請(qǐng)注意,當(dāng)你鼠標(biāo)懸停在length屬性上時(shí),VS Code的智能感知沒(méi)有提供任何信息,因?yàn)樗恢滥氵x擇使用的確切類(lèi)型。當(dāng)你像下面這樣,把其中一個(gè)添加的元素修改為其他類(lèi)型時(shí),比如number,這種不能被智能感知到的情況會(huì)體現(xiàn)得更加明顯:

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

你打出一個(gè)undefined的結(jié)果,仍然沒(méi)有什么有用信息。如果你更進(jìn)一步,決定打印string的子字符串——它會(huì)報(bào)運(yùn)行時(shí)錯(cuò)誤,但不指不出任何具體的內(nèi)容,更重要的是,編譯器沒(méi)有給出任何類(lèi)型不匹配的編譯時(shí)錯(cuò)誤?! ?/p>

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


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

理解中心思想

剛才使用any類(lèi)型導(dǎo)致的問(wèn)題,可以用TypeScript中的泛型來(lái)解決。其中心思想是類(lèi)型安全。使用泛型,你可以用一種編譯器能理解的,并且合乎我們判斷的方式,指定類(lèi)、類(lèi)型和接口的實(shí)例。正如在其他強(qiáng)類(lèi)型語(yǔ)言中的情況一樣,用這種方法,就可以在編譯時(shí)發(fā)現(xiàn)你的類(lèi)型錯(cuò)誤,從而保證了類(lèi)型安全。

泛型的語(yǔ)法像這樣:

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

你可以在之前創(chuàng)建的集合中使用泛型,用尖括號(hào)括起來(lái)。  

class Collection {
  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();
Stringss.add(001);
Stringss.add("world");
console.log(Stringss.get(0).substr(0, 1));

如果將帶有尖括號(hào)的新邏輯復(fù)制到代碼編輯器中,你會(huì)立即注意到"001"下的波浪線。這是因?yàn)?,TypeScript現(xiàn)在可以從指定的泛型類(lèi)型推斷出001不是字符串。在T出現(xiàn)的地方,就可以使用string類(lèi)型,這就實(shí)現(xiàn)了類(lèi)型安全。本質(zhì)上,這個(gè)集合的輸出可以是任何類(lèi)型,但你指明了它應(yīng)該是string類(lèi)型,所以編譯器推斷它就是string類(lèi)型。這里使用的泛型聲明是在類(lèi)級(jí)別,它也可以在其他級(jí)別定義,如靜態(tài)方法級(jí)別和實(shí)例方法級(jí)別,你稍后會(huì)看到。

使用泛型

你可以在泛型聲明中,包含多個(gè)類(lèi)型參數(shù),它們只需要用逗號(hào)分隔,像這樣:

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

聲明時(shí),類(lèi)型參數(shù)也可以在函數(shù)中顯式使用,比如:

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

因此,當(dāng)你要?jiǎng)?chuàng)建一個(gè)新的集合時(shí),在方法級(jí)別聲明的泛型,現(xiàn)在也會(huì)在方法調(diào)用級(jí)別中被指示,像這樣:  

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

你還可注意到,在鼠標(biāo)懸停時(shí),VS Code智能感知能夠推斷出第二個(gè)add函數(shù)調(diào)用仍然是string類(lèi)型。

泛型聲明同樣適用于靜態(tài)方法:

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

雖然初始化靜態(tài)方法時(shí),可使用泛型類(lèi)型,但是,對(duì)初始化靜態(tài)屬性則不能。

泛型約束

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

如果你有這樣一個(gè)非常簡(jiǎn)單的函數(shù):

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

因?yàn)門(mén)ypeScript無(wú)法推斷出arg參數(shù)是什么類(lèi)型,不能證明所有類(lèi)型都具有l(wèi)ength屬性,因此不能假設(shè)它是一個(gè)字符串(具有l(wèi)ength屬性)。所以,你會(huì)在length屬性下看到一條波浪線。如前所述,你需要?jiǎng)?chuàng)建一個(gè)接口,讓泛型的初始化可以繼承它,以便編譯器不再報(bào)警?! ?/p>

interface NameArgs {
  length: number;
}

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

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

這告訴TypeScript,可使用任何具有l(wèi)ength屬性的類(lèi)型。 定義它之后,函數(shù)調(diào)用語(yǔ)句也必須更改,因?yàn)樗辉龠m用于所有類(lèi)型。 所以它應(yīng)看起來(lái)是這樣:  

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

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

為什么是泛型

一個(gè)活躍于Stack Overflow社區(qū)的成員,Behrooz,在后續(xù)內(nèi)容中很好的回答了這個(gè)問(wèn)題。在TypeScript中使用泛型的主要原因是使類(lèi)型,類(lèi)或接口充當(dāng)參數(shù)。 它幫助我們?yōu)椴煌?lèi)型的輸入重用相同的代碼,因?yàn)轭?lèi)型本身可用作參數(shù)。

泛型的一些好處有:

定義輸入和輸出參數(shù)類(lèi)型之間的關(guān)系。比如
 

function test(input: T[]): T {
  //…
}

 

允許你確保輸入和輸出使用相同的類(lèi)型,盡管輸入是用的數(shù)組。

可使用編譯時(shí)更強(qiáng)大的類(lèi)型檢查。在上訴示例中,編譯器讓你知道數(shù)組方法可用于輸入,任何其他方法則不行。
你可以去掉不需要的強(qiáng)制類(lèi)型轉(zhuǎn)換。比如,如果你有一個(gè)常量列表:

Array a = [];

變量數(shù)組時(shí),你可以由智能感知訪問(wèn)到Item類(lèi)型的所有成員。

其他資源

官方文檔

結(jié)論

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

本文是由葡萄城技術(shù)開(kāi)發(fā)團(tuán)隊(duì)發(fā)布,轉(zhuǎn)載請(qǐng)注明出處:葡萄城官網(wǎng)

了解可嵌入您系統(tǒng)的在線 Excel,請(qǐng)前往SpreadJS純前端表格控件

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/105549.html

相關(guān)文章

  • 深入學(xué)習(xí)TypeScript

    摘要:是的超級(jí),遵循最新的規(guī)范相當(dāng)于包含了的語(yǔ)法。表示方法沒(méi)有返回任何類(lèi)型類(lèi)型表示的是那些永不存在的值的類(lèi)型,例如異常錯(cuò)誤寫(xiě)法錯(cuò)誤三函數(shù)內(nèi)容概述函數(shù)的定義可選參數(shù)默認(rèn)參數(shù)剩余參數(shù)函數(shù)重載箭頭函數(shù)。 一、Typescript 介紹、環(huán)境搭建 1.1 Typescript 介紹 1.TypeScript 是由微軟開(kāi)發(fā)的一款開(kāi)源的編程語(yǔ)言,像后端 java、C#這樣的面向?qū)ο笳Z(yǔ)言可以讓 js 開(kāi)發(fā)...

    趙連江 評(píng)論0 收藏0
  • TypeScript在React中使用總結(jié)

    摘要:事件處理我們?cè)谶M(jìn)行事件注冊(cè)時(shí)經(jīng)常會(huì)在事件處理函數(shù)中使用事件對(duì)象,例如當(dāng)使用鼠標(biāo)事件時(shí)我們通過(guò)去獲取指針的坐標(biāo)。接收,其代表事件處理函數(shù)中對(duì)象的類(lèi)型。小王沒(méi)有內(nèi)置從對(duì)象中排除是的屬性。 showImg(https://x.autoimg.cn/mall/docs/images/typescript-header.png); TypeScript 是 JS 類(lèi)型的超集,并支持了泛型、類(lèi)型、...

    lixiang 評(píng)論0 收藏0
  • 初探Java類(lèi)型擦除

    摘要:可以看到,如果我們給泛型類(lèi)制定了上限,泛型擦除之后就會(huì)被替換成類(lèi)型的上限。相應(yīng)的,泛型類(lèi)中定義的方法的類(lèi)型也是如此。參考語(yǔ)言類(lèi)型擦除下界通配符和的區(qū)別 本篇博客主要介紹了Java類(lèi)型擦除的定義,詳細(xì)的介紹了類(lèi)型擦除在Java中所出現(xiàn)的場(chǎng)景。 1. 什么是類(lèi)型擦除 為了讓你們快速的對(duì)類(lèi)型擦除有一個(gè)印象,首先舉一個(gè)很簡(jiǎn)單也很經(jīng)典的例子。 // 指定泛型為String List list1 ...

    DevTalking 評(píng)論0 收藏0
  • 理解Java中的泛型(一)

    摘要:參數(shù)化的類(lèi)型其中是參數(shù)化的類(lèi)型。類(lèi)型參數(shù)的實(shí)例或?qū)嶋H類(lèi)型參數(shù)其中是類(lèi)型參數(shù)的實(shí)例或?qū)嶋H類(lèi)型參數(shù)。它們并沒(méi)有重載,而且泛型中也不存在重載這一說(shuō)法。除此之外,我們應(yīng)該盡量地多用泛型方法,而減少對(duì)整個(gè)類(lèi)的泛化,因?yàn)榉盒头椒ǜ菀装咽虑檎f(shuō)明白。 泛型是適用于許多許多的類(lèi)型 ---《JAVA編程思想》 在Java的面向?qū)ο缶幊踢^(guò)程中, 或許你知道運(yùn)用繼承、接口等一系列面向?qū)ο蟮膭?dòng)作來(lái)實(shí)現(xiàn)代碼復(fù)用...

    YFan 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<