使用TypeScript類型注解的方法詳解
類型注解
TypeScript提供了很多數(shù)據(jù)類型,通過類型對(duì)變量進(jìn)行限制,稱之為類型注解,使用類型注解后,就不能夠隨意變更變量的類型。
以下代碼定義了一個(gè)字符串類型的變量,如果把它更改為數(shù)字類型時(shí),代碼編譯階段就會(huì)直接報(bào)錯(cuò),提示 “Type ‘number’ is not assignable to type ‘string’”。
這樣保證變量的數(shù)據(jù)類型是固定的,那么它所能使用的方法也是確定的,不會(huì)出現(xiàn)變量本來是字符串,調(diào)用了 toUpperCase方法,后來在未測(cè)試到的某場(chǎng)景無意中把它改為數(shù)字類型后,調(diào)用 toUpperCase 直接報(bào)錯(cuò)的情況。
類型推導(dǎo)
當(dāng)變量沒有寫數(shù)據(jù)類型時(shí),ts內(nèi)部會(huì)進(jìn)行"類型推導(dǎo)",通過上下文賦值語句判斷出該變量的數(shù)據(jù)類型,所以在類型注解較為簡(jiǎn)單時(shí)且其能準(zhǔn)確自動(dòng)推導(dǎo)出類型時(shí),不寫類型注解對(duì)代碼質(zhì)量也沒有影響。
TS和JS共有的數(shù)據(jù)類型
TypeScript包含了JavaScript所擁有的數(shù)據(jù)類型,string
、number
、symbol
、array
、boolean
、undefined
、null
、object
。
其中,array 在定義的時(shí)候需要加上數(shù)組中的每一個(gè)數(shù)據(jù)的類型,是字符串、數(shù)字還是對(duì)象,這就使得數(shù)組中不可以寫多種數(shù)據(jù)類型,如果有需要寫多種數(shù)據(jù)類型的情況,可以直接不加類型注解,會(huì)自動(dòng)進(jìn)行【類型推導(dǎo)】。
let str: string = "string"; let num: number = 0; let sym: symbol = Symbol("sym"); let arr1: string[] = ['alice', 'kiki', 'heidi'] let arr2: object[] = [{ name: 'alice'}] let arr3: number[] = [1, 2, 3] let flag: boolean = false; let und: undefined = undefined; let nu: null = null; let user = { name: "alice" };
上面的對(duì)象user也是沒有加類型注解的,因?yàn)槿绻x為 object 類型,無法獲取和修改user對(duì)象上的屬性。
這是因?yàn)閡ser是object類型,但object類型上沒有name屬性,所以編譯階段會(huì)直接報(bào)錯(cuò),所以對(duì)于對(duì)象可以不加類型注解,讓其自動(dòng)進(jìn)行類型推導(dǎo)。
TS獨(dú)有的數(shù)據(jù)類型
此外TypeScirpt還增加了很多JavaScript沒有的數(shù)據(jù)類型
any
any是一個(gè) “萬金油” 的數(shù)據(jù)類型,表示 “任意” 數(shù)據(jù)類型,當(dāng)變量的類型不確定且有可能發(fā)生變化時(shí),可以定義為 any,此時(shí)變量的數(shù)據(jù)類型可以被隨意更改,這其實(shí)會(huì)帶來一些安全隱患。
比如下面的代碼,將字符串當(dāng)作函數(shù)使用,undefined使用數(shù)字的方法。因?yàn)槭莂ny類型,類型有可能被改成字符串、數(shù)字、布爾值,所以這樣的代碼不會(huì)被ts檢測(cè)出問題,但在運(yùn)行時(shí)肯定是會(huì)報(bào)錯(cuò)的。
let message: any = "message"; message(); message = 0; message = undefined; message.toFixed();
unknown
當(dāng)一個(gè)變量的類型暫時(shí)不確定時(shí),可以使用unknown用來限制其類型。
let flag = true let result: unknown; if (flag) { result = 'Hello World' } else { result = 888 }
它和any有些像,但區(qū)別在于unknown是不能被賦值給除了any和unknown類型的變量,這樣使得unknown的值不能被亂用到其它地方。
void
當(dāng)函數(shù)沒有返回值時(shí),實(shí)際上返回的就是 undefined,void 通常用來表示函數(shù)返回值為 undefined 或者 null。
以下形式都是可以的
function add(): void {} function sub(): void { return undefined } function mul(): void { return null }
當(dāng)存在返回值時(shí),編譯是會(huì)報(bào)錯(cuò)的。
never
never 表示永遠(yuǎn)不會(huì)存在的類型,如果函數(shù)為死循環(huán)或者拋出異常時(shí)可以使用。
function foo(): never { while (true) {} } function catchError(): never { throw new Error("error"); }
當(dāng)我們封裝工具函數(shù)時(shí),開始規(guī)定的函數(shù)入?yún)?string 類型,但可能后續(xù)在其它人開發(fā)過程中,增加了 number 類型,為了避免維護(hù)時(shí)忘記對(duì)該類型數(shù)據(jù)進(jìn)行處理,可以把入?yún)①x值給 never 類型的變量,使得編譯不通過來防止開發(fā)者邏輯疏漏。
tuple
tuple 意思是元組,和數(shù)組比較相似,但元組和數(shù)組還是存在以下區(qū)別。
- 數(shù)組中元素?cái)?shù)據(jù)類型建議是一致的,當(dāng)數(shù)據(jù)類型不一致時(shí)考慮放到元組或者對(duì)象。
- 元組中每個(gè)元素都有自己的特性,可以通過索引值獲取。
// 數(shù)組 const array: string[] = ["alice", "kiki"]; // 元組 const tuple: [string, number] = ["alice", 20];
函數(shù)參數(shù)和返回值
聲明函數(shù)時(shí),在函數(shù)的每個(gè)參數(shù)后添加類型注解,以聲明函數(shù)接受的參數(shù)類型,限制參數(shù)類型、參數(shù)個(gè)數(shù)。
在函數(shù)列表后面定義的類型注解,用于限制函數(shù)返回值類型的。
// 限制參入類型 function foo(message: string, no: number) {} // 限制返回值 function baz(message: string): string { return "string"; }
當(dāng)入?yún)㈩愋?個(gè)數(shù)沒有達(dá)到注解要求時(shí),編譯會(huì)標(biāo)紅以提醒。
對(duì)象類型、可選類型、聯(lián)合類型 也都是可以用于規(guī)定函數(shù)入?yún)⒌摹?/p>
- 對(duì)象類型,定義對(duì)象中每個(gè)參數(shù)的數(shù)據(jù)類型
- 可選類型,用 ?表示,意味著該參數(shù)是非必傳的,必須寫在必選類型后面
- 聯(lián)合類型,用 | 表示,A | B 意味著入?yún)㈩愋褪茿和B中的任意一個(gè)
function getPoint(point: { x: number; y: number; z?: number }) {} getPoint({ x: 10, y: 20 }); getPoint({ x: 10, y: 20, z: 30 }); function printId(id: string | number) {} printId(1); printId("alice"); function foo(message?: string) {} foo("message"); foo();
當(dāng)需要規(guī)定的類型比較長(zhǎng)時(shí),可以通過 type 關(guān)鍵字來定義類型別名
同時(shí)參數(shù)類型為【可選類型】可以理解該參數(shù)類型與 undefined 的【聯(lián)合類型】,以下兩個(gè)參數(shù)的入?yún)⒈举|(zhì)上是一樣的
function foo(message?: string) {} foo("message"); foo(); function baz(message: string | undefined) {} baz("message"); baz(undefined);
類型斷言
有時(shí)候TypeScirpt獲取到的類型是比較廣泛的,這個(gè)時(shí)候可以使用類型斷言,通過關(guān)鍵字 as 定義具體數(shù)據(jù)類型。
比如以下定義了兩個(gè)類,Student 繼承自 Person 類,且擁有自己的 studying 方法,定義sayHello方法,要求入?yún)㈩愋蜑镻erson,此時(shí)創(chuàng)建Student的實(shí)例對(duì)象student,并調(diào)用sayHello方法,傳入student。
class Person {} class Student extends Person { studying(){} } function sayHello(p: Person){} const student = new Student() sayHello(student)
以上代碼在編譯的時(shí)候是沒有問題的,但如果在sayHello方法中想要調(diào)用Student實(shí)例對(duì)象的studying,是不可以的,因?yàn)殡m然傳入的參數(shù)是Student的實(shí)例對(duì)象,但它在TypeScript中只能被檢測(cè)為Person類型,而Person上是沒有studying方法的。
要想正確調(diào)用,需要使用類型斷言規(guī)定入?yún)⒌膶?shí)際類型
function sayHello(p: Person){ (p as Student).studying() }
非空類型斷言
通過 !符號(hào)來使不能通過編譯的代碼不被標(biāo)紅提醒,但如果運(yùn)行階段代碼存在問題,仍然是會(huì)拋出錯(cuò)誤的。
字面量
通過const定義的變量的數(shù)據(jù)類型為字面量類型,字面量里的值就是該變量賦值的內(nèi)容。
通過字面量類型,可用于規(guī)定變量的選擇范圍,比如 flex 布局的 direction 可以選擇 row 或者 colums
type DirectionType = "row" | "colums"; let direction: DirectionType = "row"; direction = "colums";
當(dāng)變量賦值為它類型注解中所沒有包含的內(nèi)容時(shí),是會(huì)標(biāo)紅提醒的。
類型縮小
類型縮小表示當(dāng)變量數(shù)據(jù)類型的范圍比較大時(shí),我們可以通過 if 、switch 、in 、typeof、instanceof 等方式進(jìn)行判斷來縮小的變量的類型,以達(dá)到更精準(zhǔn)的操作。
比如一個(gè)函數(shù)的參數(shù)類型可能為 string 和 number,直接獲取 length 屬性 是會(huì)報(bào)錯(cuò)的。因?yàn)橹挥?string 類型的變量可以獲取到 length,但在 number 類型上是不存在的,所以此時(shí)可以通過 typeof 來判斷入?yún)㈩愋停@個(gè)判斷步驟也稱為"類型保護(hù)"。
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
js實(shí)現(xiàn)網(wǎng)頁(yè)自動(dòng)刷新可制作節(jié)日倒計(jì)時(shí)效果
這篇文章主要介紹了通過js實(shí)現(xiàn)的網(wǎng)頁(yè)自動(dòng)刷新,利用此功能可制作節(jié)日倒計(jì)時(shí)效果,需要的朋友可以參考下2014-05-05五個(gè)基于JS實(shí)現(xiàn)的炫酷登錄頁(yè)面
本文為大家準(zhǔn)備了五個(gè)基于HTML+CSS+JS實(shí)現(xiàn)的酷炫登錄頁(yè)面的示例代碼,文中的頁(yè)面效果都很好看,需要的小伙伴可以參考一下2022-04-04JavaScript使用function定義對(duì)象并調(diào)用的方法
這篇文章主要介紹了JavaScript使用function定義對(duì)象并調(diào)用的方法,實(shí)例分析了javascript中function定義及使用對(duì)象與方法的相關(guān)技巧,需要的朋友可以參考下2015-03-03簡(jiǎn)單實(shí)用的js調(diào)試logger組件實(shí)現(xiàn)代碼
開發(fā)js組件的時(shí)間調(diào)試總是麻煩的,最常用的就是用alert或者debugger來測(cè)試js的運(yùn)行狀態(tài)。2010-11-11JavaScript請(qǐng)求后臺(tái)數(shù)據(jù)的常用方法匯總
這篇文章主要介紹了JavaScript請(qǐng)求后臺(tái)數(shù)據(jù)的幾種常用方式,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06Javascript對(duì)象中關(guān)于setTimeout和setInterval的this介紹
Javascript對(duì)象中關(guān)于setTimeout和setInterval的this介紹,需要的朋友可以參考下2012-07-07微信小程序封裝網(wǎng)絡(luò)請(qǐng)求和攔截器實(shí)戰(zhàn)步驟
這篇文章主要介紹了微信小程序封裝網(wǎng)絡(luò)請(qǐng)求和攔截器實(shí)戰(zhàn)步驟,這樣可以提高開發(fā)效率,減少代碼重復(fù),同時(shí)也可以提高代碼的可維護(hù)性和可讀性2023-03-03JavaScript實(shí)現(xiàn)手寫call/apply/bind的示例代碼
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)手寫call/apply/bind的方法,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)JavaScript有一定的幫助,需要的可以參考一下2023-02-02微信小程序wx.request實(shí)現(xiàn)后臺(tái)數(shù)據(jù)交互功能分析
這篇文章主要介紹了微信小程序wx.request實(shí)現(xiàn)后臺(tái)數(shù)據(jù)交互功能,分析微信小程序wx.request在后臺(tái)數(shù)據(jù)交互過程中遇到的問題與相關(guān)的解決方法,需要的朋友可以參考下2017-11-11