91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

typescript中keyof與typeof操作符怎么使用

發布時間:2022-06-23 09:49:55 來源:億速云 閱讀:157 作者:iii 欄目:開發技術

這篇文章主要介紹“typescript中keyof與typeof操作符怎么使用”,在日常操作中,相信很多人在typescript中keyof與typeof操作符怎么使用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”typescript中keyof與typeof操作符怎么使用”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

一、keyof 簡介

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

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 編譯器會提示以下錯誤信息:

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

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

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

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

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 是一種高度動態的語言。有時在靜態類型系統中捕獲某些操作的語義可能會很棘手。以一個簡單的prop 函數為例:

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

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

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

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

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

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

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

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

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

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

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

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) 函數,已經可以正確地推導出指定鍵對應的類型。那么當訪問 todo 對象上不存在的屬性時,會出現什么情況?比如:

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

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

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

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

三、keyof 與對象的數值屬性

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

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

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

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

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]}`);

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

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

為了方便用戶能根據貨幣類型來獲取對應的貨幣名稱,我們來定義一個 getCurrencyName 函數,具體實現如下:

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

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

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

四、keyof 與 typeof 操作符

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

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

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

type Human = typeof man;

了解完 typeof 和 keyof 操作符的作用,我們來舉個例子,介紹一下它們如何結合在一起使用:

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

// 首先通過typeof操作符獲取color變量的類型,然后通過keyof操作符獲取該類型的所有鍵,
// 即字符串字面量聯合類型 '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

到此,關于“typescript中keyof與typeof操作符怎么使用”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

永平县| 沽源县| 海淀区| 凉城县| 阿坝| 华坪县| 赣州市| 进贤县| 罗城| 湘阴县| 莫力| 虹口区| 滨州市| 伽师县| 辉南县| 老河口市| 任丘市| 宁化县| 驻马店市| 台江县| 子长县| 庄河市| 华容县| 宾阳县| 青岛市| 闸北区| 山西省| 太仆寺旗| 汽车| 曲靖市| 阳新县| 班玛县| 贺兰县| 新密市| 长治县| 拉萨市| 临武县| 于田县| 将乐县| 忻城县| 宁河县|