淺談typescript中keyof與typeof操作符用法_第1頁
淺談typescript中keyof與typeof操作符用法_第2頁
淺談typescript中keyof與typeof操作符用法_第3頁
淺談typescript中keyof與typeof操作符用法_第4頁
淺談typescript中keyof與typeof操作符用法_第5頁
已閱讀5頁,還剩2頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第淺談typescript中keyof與typeof操作符用法目錄一、keyof簡介二、keyof的作用三、keyof與對象的數(shù)值屬性四、keyof與typeof操作符

一、keyof簡介

TypeScript允許我們遍歷某種類型的屬性,并通過keyof操作符提取其屬性的名稱。keyof操作符是在TypeScript2.1版本引入的,該操作符可以用于獲取某種類型的所有鍵,其返回類型是聯(lián)合類型。

下面我們來看個例子:

interfacePerson{

name:string;

age:number;

location:string;

typeK1=keyofPerson;//"name"|"age"|"location"

typeK2=keyofPerson[];

//number|"length"|"push"|"concat"|...

typeK3=keyof{[x:string]:Person};

//string|number

除了接口外,keyof也可以用于操作類,比如:

classPerson{

name:string="Semlinker";

letsname:keyofPerson;

sname="name";

若把sname=name改為sname=age的話,TypeScript編譯器會提示以下錯誤信息:

Typeageisnotassignabletotypename.

keyof操作符除了支持接口和類之外,它也支持基本數(shù)據(jù)類型:

letK1:keyofboolean;//letK1:valueOf

letK2:keyofnumber;//letK2:toString|toFixed|toExponential|...

letK3:keyofsymbol;//letK1:valueOf

此外keyof也稱為輸入索引類型查詢,與之相對應(yīng)的是索引訪問類型,也稱為查找類型。在語法上,它們看起來像屬性或元素訪問,但最終會被轉(zhuǎn)換為類型:

typeP1=Person["name"];//string

typeP2=Person["name"|"age"];//string|number

typeP3=string["charAt"];//(pos:number)=string

typeP4=string[]["push"];//(...items:string[])=number

typeP5=string[][0];//string

二、keyof的作用

JavaScript是一種高度動態(tài)的語言。有時在靜態(tài)類型系統(tǒng)中捕獲某些操作的語義可能會很棘手。以一個簡單的prop函數(shù)為例:

functionprop(obj,key){

returnobj[key];

}

該函數(shù)接收obj和key兩個參數(shù),并返回對應(yīng)屬性的值。對象上的不同屬性,可以具有完全不同的類型,我們甚至不知道obj對象長什么樣。

那么在TypeScript中如何定義上面的prop函數(shù)呢?我們來嘗試一下:

functionprop(obj:object,key:string){

returnobj[key];

}

在上面代碼中,為了避免調(diào)用prop函數(shù)時傳入錯誤的參數(shù)類型,我們?yōu)閛bj和key參數(shù)設(shè)置了類型,分別為{}和string類型。然而,事情并沒有那么簡單。針對上述的代碼,TypeScript編譯器會輸出以下錯誤信息:

Elementimplicitlyhasananytypebecauseexpressionoftypestringcantbeusedtoindextype{}

元素隱式地擁有any類型,因為string類型不能被用于索引{}類型。要解決這個問題,你可以使用以下非常暴力的方案:

functionprop(obj:object,key:string){

return(objasany)[key];

}

很明顯該方案并不是一個好的方案,我們來回顧一下prop函數(shù)的作用,該函數(shù)用于獲取某個對象中指定屬性的屬性值。因此我們期望用戶輸入的屬性是對象上已存在的屬性,那么如何限制屬性名的范圍呢?這時我們可以利用本文的主角keyof操作符:

functionpropTextendsobject,KextendskeyofT(obj:T,key:K){

returnobj[key];

}

在以上代碼中,我們使用了TypeScript的泛型和泛型約束。首先定義了T類型并使用extends關(guān)鍵字約束該類型必須是object類型的子類型,然后使用keyof操作符獲取T類型的所有鍵,其返回類型是聯(lián)合類型,最后利用extends關(guān)鍵字約束K類型必須為keyofT聯(lián)合類型的子類型。是騾子是馬拉出來遛遛就知道了,我們來實際測試一下:

typeTodo={

id:number;

text:string;

done:boolean;

consttodo:Todo={

id:1,

text:"LearnTypeScriptkeyof",

done:false

functionpropTextendsobject,KextendskeyofT(obj:T,key:K){

returnobj[key];

constid=prop(todo,"id");//constid:number

consttext=prop(todo,"text");//consttext:string

constdone=prop(todo,"done");//constdone:boolean

很明顯使用泛型,重新定義后的propTextendsobject,KextendskeyofT(obj:T,key:K)函數(shù),已經(jīng)可以正確地推導(dǎo)出指定鍵對應(yīng)的類型。那么當(dāng)訪問todo對象上不存在的屬性時,會出現(xiàn)什么情況?比如:

constdate=prop(todo,"date");

對于上述代碼,TypeScript編譯器會提示以下錯誤:

Argumentoftypedateisnotassignabletoparameteroftypeid|text|done.

這就阻止我們嘗試讀取不存在的屬性。

三、keyof與對象的數(shù)值屬性

在使用對象的數(shù)值屬性時,我們也可以使用keyof關(guān)鍵字。請記住,如果我們定義一個帶有數(shù)值屬性的對象,那么我們既需要定義該屬性,又需要使用數(shù)組語法訪問該屬性,如下所示:

classClassWithNumericProperty{

[1]:string="Semlinker";

letclassWithNumeric=newClassWithNumericProperty();

console.log(`${classWithNumeric[1]}`);

下面我們來舉個示例,介紹一下在含有數(shù)值屬性的對象中,如何使用keyof操作符來安全地訪問對象的屬性:

enumCurrency{

CNY=6,

EUR=8,

USD=10

constCurrencyName={

[Currency.CNY]:"人民幣",

[Currency.EUR]:"歐元",

[Currency.USD]:"美元"

console.log(`CurrencyName[Currency.CNY]=${CurrencyName[Currency.CNY]}`);

console.log(`CurrencyName[36]=${CurrencyName[6]}`);

上面的代碼中,首先定義了一個Currency枚舉用于表示三種貨幣類型,接著定義一個CurrencyName對象,該對象使用數(shù)值屬性作為鍵,對應(yīng)的值是該貨幣類型的名稱。該代碼成功運行后,控制臺會輸出以下結(jié)果:

CurrencyName[Currency.CNY]=人民幣

CurrencyName[36]=人民幣

為了方便用戶能根據(jù)貨幣類型來獲取對應(yīng)的貨幣名稱,我們來定義一個getCurrencyName函數(shù),具體實現(xiàn)如下:

functiongetCurrencyNameT,KextendskeyofT(key:K,map:T):T[K]{

returnmap[key];

console.log(`name=${getCurrencyName(Currency.CNY,CurrencyName)}`);

同樣,getCurrencyName函數(shù)和前面介紹的prop函數(shù)一樣,使用了泛型和泛型約束,從而來保證屬性的安全訪問。最后,我們來簡單介紹一下keyof與typeof操作符如何配合使用。

四、keyof與typeof操作符

typeof操作符用于獲取變量的類型。因此這個操作符的后面接的始終是一個變量,且需要運用到類型定義當(dāng)中。為了方便大家理解,我們來舉一個具體的示例:

typePerson={

name:string;

age:number;

letman:Person={

name:"Semlinker",

age:30

typeHuman=typeofman;

了解完typeof和keyof操作符的作用,我們來舉個例子,介紹一下它們?nèi)绾谓Y(jié)合在一起使用:

constCOLORS={

red:'red',

blue:'blue'

//首先通過typeof操作符獲取color變量的類型,然后通過keyof操作符獲取該類型的所有鍵,

//即字符串字面量聯(lián)合類型'red'|'blue'

typeColors=keyoftypeofCOLORS

letcolor:Colors;

color='red'//Ok

color='blue'//Ok

//Type'"yellow"'isnotassignabletotype'"red"|"blue"'.

color='yellow'//Error

最后

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論