日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
一文學(xué)懂TypeScript的類型

 你將學(xué)到什么

專業(yè)領(lǐng)域包括網(wǎng)站制作、成都網(wǎng)站制作、商城網(wǎng)站定制開發(fā)、微信營銷、系統(tǒng)平臺開發(fā), 與其他網(wǎng)站設(shè)計及系統(tǒng)開發(fā)公司不同,創(chuàng)新互聯(lián)公司的整合解決方案結(jié)合了幫做網(wǎng)絡(luò)品牌建設(shè)經(jīng)驗和互聯(lián)網(wǎng)整合營銷的理念,并將策略和執(zhí)行緊密結(jié)合,為客戶提供全網(wǎng)互聯(lián)網(wǎng)整合方案。

閱讀本文后,你應(yīng)該能夠理解以下代碼的含義: 

 
 
 
  1. interface Array {  
  2.   concat(...items: Array): T[];  
  3.   reduce(  
  4.     callback: (state: U, element: T, index: number, array: T[]) => U,  
  5.     firstState?: U): U;  
  6.   ···  

如果你認(rèn)為這段代碼非常神秘 —— 那么我同意你的意見。但是(我希望證明)這些符號還是相對容易學(xué)習(xí)的。一旦你能理解它們,就能馬上全面、精確的理解這種代碼,從而無需再去閱讀冗長的英文說明。

運行代碼案例

TypeScript 有一個在線運行環(huán)境。為了得到最全面的信息,你應(yīng)該在 “Options” 菜單中打開所有選項開關(guān)。這相當(dāng)于在 --strict 模式下運行TypeScript編譯器。

關(guān)于類型檢查的詳細說明

我在用 TypeScript 時總是喜歡打開 --strict 開關(guān)設(shè)置。沒有它,程序可能會稍微好寫一點,但是你也失去了靜態(tài)類型檢查的好處。目前此設(shè)置能夠開啟以下子設(shè)置:

  •     --noImplicitAny:如果 TypeScript 無法推斷類型,則必須指定它。這主要用于函數(shù)和方法的參數(shù):使用此設(shè)置,你必須對它們進行注釋。
    •   --noImplicitThis:如果 this 的類型不清楚則會給出提示信息。
    •   --alwaysStrict:盡可能使用 JavaScript 的嚴(yán)格模式。
    •   --strictNullChecks:null 不屬于任何類型(除了它自己的類型,null),如果它是可接受的值,則必須明確指定。
    •   --strictFunctionTypes:對函數(shù)類型更加嚴(yán)格的檢查。
    •   --strictPropertyInitialization:如果屬性的值不能是 undefined ,那么它必須在構(gòu)造函數(shù)中進行初始化。

更多信息:TypeScript 手冊中的“編譯器選項”一章。

類型

在本文中,我們把類型看作是一組值的集合。 JavaScript 語言(不是TypeScript?。┯?種類型:

  •  Undefined:具有***元素 undefined 的集合。
  •  Null:具有***元素“null”的集合。
  •  Boolean:具有兩個元素 false 和 true 的集合。
  •  Number:所有數(shù)字的集合。
  •  String:所有字符串的集合。
  •  Symbol:所有符號的集合。
  •  Object:所有對象的集合(包括函數(shù)和數(shù)組)。

所有這些類型都是 dynamic:可以用在運行時。

TypeScript 為 JavaScript 帶來了額外的層:靜態(tài)類型。這些僅在編譯或類型檢查源代碼時存在。每個存儲位置(變量或?qū)傩裕┒加幸粋€靜態(tài)類型,用于預(yù)測其動態(tài)值。類型檢查可確保這些預(yù)測能夠?qū)崿F(xiàn)。還有很多可以進行 靜態(tài) 檢查(不運行代碼)的東西。例如,如果函數(shù) f(x) 的參數(shù) x 是靜態(tài)類型 number,則函數(shù)調(diào)用 f('abc') 是非法的,因為參數(shù) 'abc' 是錯誤的靜態(tài)類型。

類型注釋

變量名后的冒號開始 類型注釋:冒號后的類型簽名用來描述變量可以接受的值。例如以代碼告訴 TypeScript 變量 “x” 只能存儲數(shù)字: 

 
 
 
  1. let x: number; 

你可能想知道用 undefined 去初始化 x 是不是違反了靜態(tài)類型。 TypeScript 不會允許這種情況出現(xiàn),因為在為它賦值之前不允許操作 x。

類型推斷

即使在 TypeScript 中每個存儲位置都有靜態(tài)類型,你也不必總是明確的去指定它。 TypeScript 通常可以對它的類型進行推斷。例如如果你寫下這行代碼: 

 
 
 
  1. let x = 123; 

然后 TypeScript 會推斷出 x 的靜態(tài)類型是 number。

類型描述

在類型注釋的冒號后面出現(xiàn)的是所謂的類型表達式。這些范圍從簡單到復(fù)雜,并按如下方式創(chuàng)建。

基本類型是有效的類型表達式:

  •  對應(yīng) JavaScript 動態(tài)類型的靜態(tài)類型:   
 
 
 
  1. - `undefined`, `null`  
  2.    - `boolean`, `number`, `string`  
  3.    - `symbol`  
  4.    - `object` 
  •   注意:值 undefined 與類型 undefined(取決于所在的位置)
  •  TypeScript 的特定類型:
    •   Array(從技術(shù)上講不是 JS 中的類型)
    •   any(所有值的類型)
    •   等等其他類型

請注意,“undefined作為值“ 和 ”undefined作為類型” 都寫做 undefined。根據(jù)你使用它的位置,被解釋為值或類型。 null 也是如此。

你可以通過類型運算符對基本類型進行組合的方式來創(chuàng)建更多的類型表達式,這有點像使用運算符 union(∪)和intersection(∩)去合并集合。

下面介紹 TypeScript 提供的一些類型運算符。

數(shù)組類型

數(shù)組在 JavaScript 中扮演以下兩個角色(有時是兩者的混合):

  •  列表:所有元素都具有相同的類型。數(shù)組的長度各不相同。
  •  元組:數(shù)組的長度是固定的。元素不一定具有相同的類型。

數(shù)組作為列表

數(shù)組 arr 被用作列表有兩種方法表示 ,其元素都是數(shù)字: 

 
 
 
  1. let arr: number[] = [];  
  2. let arr: Array = []; 

通常如果存在賦值的話,TypeScript 就可以推斷變量的類型。在這種情況下,實際上你必須幫它解決類型問題,因為在使用空數(shù)組時,它無法確定元素的類型。

稍后我們將回到尖括號表示法(Array)。

數(shù)組作為元組

如果你想在數(shù)組中存儲二維坐標(biāo)點,那么就可以把這個數(shù)組當(dāng)作元組去用??瓷先ナ沁@個樣子: 

 
 
 
  1. let point: [number, number] = [7, 5]; 

在這種情況下,你不需要類型注釋。

另外一個例子是 Object.entries(obj) 的返回值:一個帶有一個 [key,value] 對的數(shù)組,它用于描述 obj 的每個屬性。 

 
 
 
  1. > Object.entries({a:1, b:2})  
  2. [ [ 'a', 1 ], [ 'b', 2 ] ] 

Object.entries() 的返回值類型是: 

 
 
 
  1. Array<[string, any]> 

函數(shù)類型

以下是函數(shù)類型的例子: 

 
 
 
  1. (num: number) => string 

這個類型是一個函數(shù),它接受一個數(shù)字類型參數(shù)并且返回值為字符串。在類型注釋中使用這種類型(String 在這里是個函數(shù))的例子: 

 
 
 
  1. const func: (num: number) => string = String; 

同樣,我們一般不會在這里使用類型注釋,因為 TypeScript 知道 String 的類型,因此可以推斷出 func 的類型。

以下代碼是一個更實際的例子: 

 
 
 
  1. function stringify123(callback: (num: number) => string) {  
  2.   return callback(123);  

由于我們使用了函數(shù)類型來描述 stringify123() 的參數(shù) callback,所以TypeScript 拒絕以下函數(shù)調(diào)用。 

 
 
 
  1. f(Number); 

但它接受以下函數(shù)調(diào)用: 

 
 
 
  1. f(String); 

函數(shù)聲明的返回類型

對函數(shù)的所有參數(shù)進行注釋是一個很好的做法。你還可以指定返回值類型(不過 TypeScript 非常擅長去推斷它): 

 
 
 
  1. function stringify123(callback: (num: number) => string): string {  
  2.   const num = 123;  
  3.   return callback(num);  

特殊返回值類型 void

void 是函數(shù)的特殊返回值類型:它告訴 TypeScript 函數(shù)總是返回 undefined(顯式或隱式): 

 
 
 
  1. function f1(): void { return undefined } // OK  
  2. function f2(): void { } // OK  
  3. function f3(): void { return 'abc' } // error 

可選參數(shù)

標(biāo)識符后面的問號表示該參數(shù)是可選的。例如: 

 
 
 
  1. function stringify123(callback?: (num: number) => string) {  
  2.   const num = 123;  
  3.   if (callback) {  
  4.     return callback(num); // (A)  
  5.   }  
  6.   return String(num);  

在 --strict 模式下運行 TypeScript 時,如果事先檢查時發(fā)現(xiàn) callback 沒有被省略,它只允許你在 A 行進行函數(shù)調(diào)用。

參數(shù)默認(rèn)值

TypeScript支持 ES6 參數(shù)默認(rèn)值: 

 
 
 
  1. function createPoint(x=0, y=0) {  
  2.   return [x, y];  

默認(rèn)值可以使參數(shù)可選。通??梢允÷灶愋妥⑨專驗?TypeScript 可以推斷類型。例如它可以推斷出 x 和 y 都是 number 類型。

如果要添加類型注釋,應(yīng)該這樣寫: 

 
 
 
  1. function createPoint(x:number = 0, y:number = 0) {  
  2.   return [x, y];  

rest 類型

你還可以用 ES6 rest operator 進行 TypeScript 參數(shù)定義。相應(yīng)參數(shù)的類型必須是數(shù)組: 

 
 
 
  1. function joinNumbers(...nums: number[]): string {  
  2.     return nums.join('-');  
  3. }  
  4. joinNumbers(1, 2, 3); // '1-2-3' 

Union

在JavaScript中,有時候變量會是有幾種類型之中的一種。要描述這些變量,可以使用 union types。例如,在下面的代碼中,x 是 null 類型或 number 類型: 

 
 
 
  1. let x = null;  
  2. x = 123; 

x 的類型可以描述為 null | number: 

 
 
 
  1. let x: null|number = null;  
  2. x = 123; 

類型表達式 s | t 的結(jié)果是類型 s 和 t 在集合理論意義上的聯(lián)合(正如我們之前看到的那樣,兩個集合)。

下面讓我們重寫函數(shù) stringify123():這次我們不希望參數(shù) callback 是可選的。應(yīng)該總是調(diào)用它。如果調(diào)用者不想傳入一個函數(shù),則必須顯式傳遞 null。實現(xiàn)如下。 

 
 
 
  1. function stringify123(  
  2.   callback: null | ((num: number) => string)) {  
  3.   const num = 123;  
  4.   if (callback) { // (A)  
  5.     return callback(123); // (B)  
  6.   }  
  7.   return String(num);  

請注意,在行 B 進行函數(shù)調(diào)用之前,我們必須再次檢查 callback 是否真的是一個函數(shù)(行A)。如果沒有檢查,TypeScript 將會報告錯誤。

Optional 與 undefined|T

類型為 T 的可選參數(shù)和類型為 undefined|T 的參數(shù)非常相似。 (另外對于可選屬性也是如此。)

主要區(qū)別在于你可以省略可選參數(shù): 

 
 
 
  1. function f1(x?: number) { }  
  2. f1(); // OK  
  3. f1(undefined); // OK  
  4. f1(123); // OK 

But you can’t omit parameters of type

但是你不能省略 undefined|T 類型的參數(shù): 

 
 
 
  1. function f2(x: undefined | number) { }  
  2. f2(); // error  
  3. f2(undefined); // OK  
  4. f2(123); // OK 

值 null 和 undefined 通常不包含在類型中

在許多編程語言中,null 是所有類型的一部分。例如只要 Java 中的參數(shù)類型為 String,就可以傳遞 null 而Java 不會報錯。

相反,在TypeScript中,undefined 和 null 由單獨的不相交類型處理。如果你想使它們生效,必須要有一個類型聯(lián)合,如 undefined|string 和 null|string。

對象

與Arrays類似,對象在 JavaScript 中扮演兩個角色(偶爾混合和/或更加動態(tài)):

  •  記錄:在開發(fā)時已知的固定數(shù)量的屬性。每個屬性可以有不同的類型。
  •  字典:在開發(fā)時名稱未知的任意數(shù)量的屬性。所有屬性鍵(字符串和/或符號)都具有相同的類型,屬性值也是如此。

我們將在本文章中忽略 object-as-dictionaries。順便說一句,無論如何,map 通常是比字典的更好選擇。

通過接口描述 objects-as-records

接口描述 objects-as-records 。例如: 

 
 
 
  1. interface Point {  
  2.   x: number;  
  3.   y: number;  

TypeScript 類型系統(tǒng)的一大優(yōu)勢在于它的結(jié)構(gòu)上,而不是在命名上。也就是說,接口 Point 能夠匹配適當(dāng)結(jié)構(gòu)的所有對象: 

 
 
 
  1. function pointToString(p: Point) {  
  2.   return `(${p.x}, ${p.y})`;  
  3. }  
  4. pointToString({x: 5, y: 7}); // '(5, 7)' 

相比之下,Java 的標(biāo)稱類型系統(tǒng)需要類來實現(xiàn)接口。

可選屬性

如果可以省略屬性,則在其名稱后面加上一個問號: 

 
 
 
  1. interface Person {  
  2.   name: string;  
  3.   company?: string;  

方法

接口內(nèi)還可以包含方法: 

 
 
 
  1. interface Point {  
  2.   x: number;  
  3.   y: number;  
  4.   distance(other: Point): number;  

類型變量和泛型類型

使用靜態(tài)類型,可以有兩個級別:

  •  值存在于對象級別。
  •  類型存在于元級別。

同理:

  •  普通變量定義在對象級別之上。
  •  類型變量存在于元級別之上。它們是值為類型的變量。

普通變量通過 const,let 等引入。類型變量通過尖括號( <> )引入。例如以下代碼包含類型變量 T,通過 引入。 

 
 
 
  1. interface Stack {  
  2.   push(x: T): void;  
  3.   pop(): T;  

你可以看到類型參數(shù) T 在 Stack 的主體內(nèi)出現(xiàn)兩次。因此,該接口可以直觀地理解如下:

  •  Stack 是一堆值,它們都具有給定的類型 T。每當(dāng)你提到 Stack 時,必須寫 T。接下來我們會看到究竟該怎么用。
  •  方法 .push() 接受類型為 T 的值。
  •  方法 .pop() 返回類型為 T 的值。

如果使用 Stack,則必須為 T 指定一個類型。以下代碼顯示了一個虛擬棧,其***目的是匹配接口。 

 
 
 
  1. const dummyStack: Stack = {  
  2.   push(x: number) {},  
  3.   pop() { return 123 },  
  4. }; 

例子:map

map 在 TypeScript 中的定義。例如: 

 
 
 
  1. const myMap: Map = new Map([  
  2.   [false, 'no'],  
  3.   [true, 'yes'],  
  4. ]); 

函數(shù)的類型變量

函數(shù)(和方法)也可以引入類型變量: 

 
 
 
  1. function id(x: T): T {  
  2.   return x;  

你可以按以下方式使用此功能。 

 
 
 
  1. id(123); 

由于類型推斷,還可以省略類型參數(shù): 

 
 
 
  1. id(123); 

傳遞類型參數(shù)

函數(shù)可以將其她的類型參數(shù)傳給接口、類等: 

 
 
 
  1. function fillArray(len: number, elem: T) {  
  2.   return new Array(len).fill(elem);  

類型變量 T 在這段代碼中出現(xiàn)三次:

  •  fillArray:引入類型變量
  •  elem:T:使用類型變量,從參數(shù)中選擇它。
  •  Array:將 T 傳遞給 Array 的構(gòu)造函數(shù)。

這意味著:我們不必顯式指定Array的類型 T —— 它是從參數(shù) elem中推斷出來的: 

 
 
 
  1. const arr = fillArray(3, '*');  
  2.   // Inferred type: string[] 

總結(jié)

讓我們用前面學(xué)到的知識來理解最開始看到的那段代碼: 

 
 
 
  1. interface Array {  
  2.   concat(...items: Array): T[];  
  3.   reduce(  
  4.     callback: (state: U, element: T, index: number, array: T[]) => U,  
  5.     firstState?: U): U;  
  6.   ···  

這是一個Array的接口,其元素類型為 T,每當(dāng)使用這個接口時必須填寫它:

  •  方法.concat()有零個或多個參數(shù)(通過 rest 運算符定義)。其中每一個參數(shù)中都具有類型 T[]|T。也就是說,它是一個 T 類型的數(shù)組或是一個 T 值。
  •  方法.reduce() 引入了自己的類型變量 U。 U 表示以下實體都具有相同的類型(你不需要指定,它是自動推斷的):
    •   Parameter state of callback() (which is a function)
    •   state 是 callback() 的參數(shù)(這是一個函數(shù))
      •   Result of callback() 
    •   callback()的返回
    •    reduce()的可選參數(shù) firstState
      •   Result of .reduce() 
    •    reduce()的返回

callback 還將獲得一個 element 參數(shù),其類型與 Array 元素具有相同的類型 T,參數(shù) index 是一個數(shù)字,參數(shù) array 是 T 的值。


當(dāng)前名稱:一文學(xué)懂TypeScript的類型
鏈接地址:http://m.5511xx.com/article/cdhgdgi.html