" />

最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談typescript中keyof與typeof操作符用法

 更新時(shí)間:2022年06月22日 11:36:06   作者:金剛腿  
本文主要介紹了typescript中keyof與typeof操作符用法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

一、keyof 簡(jiǎn)介

TypeScript 允許我們遍歷某種類型的屬性,并通過 keyof 操作符提取其屬性的名稱。keyof 操作符是在 TypeScript 2.1 版本引入的,該操作符可以用于獲取某種類型的所有鍵,其返回類型是聯(lián)合類型。
下面我們來看個(gè)例子:

interface Person {
? name: string;
? age: number;
? location: string;
}

type K1 = keyof Person; // "name" | "age" | "location"
type K2 = keyof Person[]; ?// number | "length" | "push" | "concat" | ...
type K3 = keyof { [x: string]: Person }; ?// string | number

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

class Person {
? name: string = "Semlinker";
}

let sname: keyof Person;
sname = "name";

若把 sname = “name” 改為 sname = “age” 的話,TypeScript 編譯器會(huì)提示以下錯(cuò)誤信息:

Type '"age"' is not assignable to type '"name"'.

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

let K1: keyof boolean; // let K1: "valueOf"
let K2: keyof number; // let K2: "toString" | "toFixed" | "toExponential" | ...
let K3: keyof symbol; // let K1: "valueOf"

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

type P1 = Person["name"];  // string
type P2 = Person["name" | "age"];  // string | number
type P3 = string["charAt"];  // (pos: number) => string
type P4 = string[]["push"];  // (...items: string[]) => number
type P5 = string[][0];  // string

二、keyof 的作用

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

function prop(obj, key) {
  return obj[key];
}

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

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

function prop(obj: object, key: string) {
  return obj[key];
}

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

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'

元素隱式地?fù)碛?any 類型,因?yàn)?string 類型不能被用于索引 {} 類型。要解決這個(gè)問題,你可以使用以下非常暴力的方案:

function prop(obj: object, key: string) {
  return (obj as any)[key];
}

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

function prop<T extends object, K extends keyof T>(obj: T, key: K) {
  return obj[key];
}

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

type Todo = {
? id: number;
? text: string;
? done: boolean;
}

const todo: Todo = {
? id: 1,
? text: "Learn TypeScript keyof",
? done: false
}

function prop<T extends object, K extends keyof T>(obj: T, key: K) {
? return obj[key];
}

const id = prop(todo, "id"); // const id: number
const text = prop(todo, "text"); // const text: string
const done = prop(todo, "done"); // const done: boolean

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

const date = prop(todo, "date");

對(duì)于上述代碼,TypeScript 編譯器會(huì)提示以下錯(cuò)誤:

Argument of type '"date"' is not assignable to parameter of type '"id" | "text" | "done"'.

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

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

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

class ClassWithNumericProperty {
? [1]: string = "Semlinker";
}

let classWithNumeric = new ClassWithNumericProperty();
console.log(`${classWithNumeric[1]} `);

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

enum Currency {
? CNY = 6,
? EUR = 8,
? USD = 10
}

const CurrencyName = {
? [Currency.CNY]: "人民幣",
? [Currency.EUR]: "歐元",
? [Currency.USD]: "美元"
};

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

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

CurrencyName[Currency.CNY] = 人民幣
CurrencyName[36] = 人民幣

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

function getCurrencyName<T, K extends keyof T>(key: K, map: T): T[K] {
? return map[key];
}

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

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

四、keyof 與 typeof 操作符

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

type Person = {
? name: string;
? age: number;
}

let man: Person = {
? name: "Semlinker",
? age: 30
}

type Human = typeof man;

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

const COLORS = {
? red: 'red',
? blue: 'blue'
}

// 首先通過typeof操作符獲取color變量的類型,然后通過keyof操作符獲取該類型的所有鍵,
// 即字符串字面量聯(lián)合類型 'red' | 'blue'

type Colors = keyof typeof COLORS?
let color: Colors;
color = 'red' // Ok
color = 'blue' // Ok

// Type '"yellow"' is not assignable to type '"red" | "blue"'.
color = 'yellow' // Error

最后留到思考題,有興趣的小伙伴可以想一想:

interface StringIndexArray {
? [index: string]: string;
}

interface NumberIndexArray {
? [index: number]: string;
}

type K1 = keyof StringIndexArray // type K1 = string | number
type K2 = keyof NumberIndexArray // type K2 = number

到此這篇關(guān)于淺談typescript中keyof與typeof操作符用法的文章就介紹到這了,更多相關(guān)typescript中keyof與typeof操作符內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • require簡(jiǎn)單實(shí)現(xiàn)單頁應(yīng)用程序(SPA)

    require簡(jiǎn)單實(shí)現(xiàn)單頁應(yīng)用程序(SPA)

    下面小編就為大家?guī)硪黄猺equire簡(jiǎn)單實(shí)現(xiàn)單頁應(yīng)用程序(SPA)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-07-07
  • 詳解webpack引用jquery(第三方模塊)的三種辦法

    詳解webpack引用jquery(第三方模塊)的三種辦法

    這篇文章主要介紹了詳解webpack引用jquery(第三方模塊)的三種辦法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Cropper.js進(jìn)階之固定寬高圖片裁切實(shí)現(xiàn)示例

    Cropper.js進(jìn)階之固定寬高圖片裁切實(shí)現(xiàn)示例

    這篇文章主要為大家介紹了Cropper.js進(jìn)階之固定寬高圖片裁切實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • JavaScript實(shí)現(xiàn)彈出廣告功能

    JavaScript實(shí)現(xiàn)彈出廣告功能

    本文通過實(shí)例代碼給大家分享javascript實(shí)現(xiàn)彈出廣告功能,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧
    2017-03-03
  • uniapp使用uni.chooseLocation()打開地圖選擇位置詳解

    uniapp使用uni.chooseLocation()打開地圖選擇位置詳解

    這篇文章主要給大家介紹了關(guān)于uniapp使用uni.chooseLocation()打開地圖選擇位置的相關(guān)資料,因?yàn)樽罱陧?xiàng)目中遇到一個(gè)要用戶授權(quán)位置且可以用戶自己選擇位置的功能,需要的朋友可以參考下
    2023-06-06
  • JS實(shí)現(xiàn)數(shù)組過濾從簡(jiǎn)單到多條件篩選

    JS實(shí)現(xiàn)數(shù)組過濾從簡(jiǎn)單到多條件篩選

    一般情況下的單條件篩選,數(shù)組的filter方法就能夠滿足需求,本文討論的重點(diǎn)是多條件下的復(fù)合篩選,并列出了幾個(gè)相關(guān)知識(shí)點(diǎn),感興趣的可以了解一下
    2021-07-07
  • JavaScript 事件系統(tǒng)

    JavaScript 事件系統(tǒng)

    今天比較系統(tǒng)都學(xué)習(xí)了 JavaScript 的事件系統(tǒng)。
    2010-07-07
  • bootstrap手風(fēng)琴制作方法詳解

    bootstrap手風(fēng)琴制作方法詳解

    這篇文章主要為大家詳細(xì)介紹了bootstrap手風(fēng)琴的制作方法,制作聲明式觸發(fā)手風(fēng)琴,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • js+CSS實(shí)現(xiàn)彈出居中背景半透明div層的方法

    js+CSS實(shí)現(xiàn)彈出居中背景半透明div層的方法

    這篇文章主要介紹了js+CSS實(shí)現(xiàn)彈出居中背景半透明div層的方法,涉及javascript操作彈出div層的操作技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-02-02
  • iScroll中事件點(diǎn)擊觸發(fā)兩次解決方案

    iScroll中事件點(diǎn)擊觸發(fā)兩次解決方案

    iScroll是我們?cè)谧鍪謾C(jī)網(wǎng)頁中常用的滑動(dòng)控件之一。單說其功能已相當(dāng)豐富。但個(gè)別時(shí)候也是會(huì)掉坑的,正好這次就遇上了。在android的app中嵌入網(wǎng)頁時(shí)不少手機(jī)會(huì)出現(xiàn)一次點(diǎn)擊兩次觸發(fā)的現(xiàn)象。經(jīng)過一段時(shí)間的折騰,總算想到了一個(gè)還算合理的解決放案。
    2015-03-03

最新評(píng)論

涪陵区| 隆德县| 准格尔旗| 尚义县| 太保市| 牙克石市| 宁阳县| 武宁县| 西乡县| 积石山| 洛川县| 当雄县| 永昌县| 宾川县| 临邑县| 阿拉善盟| 兴义市| 禹州市| 临城县| 宁陕县| 盘锦市| 阿合奇县| 祁连县| 婺源县| 台北市| 开平市| 金坛市| 阳朔县| 化隆| 保山市| 宜兴市| 茂名市| 岑溪市| 乌兰县| 永定县| 大关县| 东乡族自治县| 东丽区| 策勒县| 阜宁县| 达州市|