keyof 用來返回一個class類型或者interface類型的全部key組成的聯合類型。能夠看下面的一個例子:prototype
type Point = { 0: number; height: number }; interface Point2{name: string; age: number} type KeyOfPoint = keyof Point; // 0 | 'height' type KeyOfPoint2 = keyof Point2; // 'name' | 'age' const fn = (key: KeyOfPoint | KeyOfPoint2)=>{} fn(0) //no error fn('height') //no error fn('name') //no error fn('age') //no error fn('width') // error: 類型不匹配
在以上的代碼裏面 :設計
key: KeyOfPoint | KeyOfPoint2
就至關於:code
key: 0 | 'height' | 'name' | 'age'
因此,當咱們調用:fn('width')
的時候就會報錯,由於‘width’不在Point和Point2的key的列表裏面。對象
number類型的index signature, 結果爲: number
ip
type Arrayish = { [n: number]: unknown }; type A = keyof Arrayish; // type A = number
string類型的index signature,結果爲: string | number
。這是由於,當我定義string類型的index signature時,我依然能夠給number類型的key,由於JavaScript會把對象的number類型的key強制轉爲string,好比obj[0]和obj['0']是相等的。ci
type Arrayish = { [n: string]: unknown }; type A = keyof Arrayish; // type A = number | number const fn = (key: A)=>{} fn('xxx') // no error fn(0) // no error
以上是keyof的一般使用場景,也是keyof被設計出來的初衷。可是,假如咱們把keyof用到enum, number,string等類型上會獲得什麼呢?string
enum Colors { red, blue, yellow } type A = keyof Colors; // "toString" | "toFixed" | "toExponential" | "toPrecision" | "valueOf" | "toLocaleString"
當把keyof用在number類型的enum上時,會獲得Number.prototype
上所定義的方法的名字(string格式)的聯合類型。io
enum Colors { red = 'red', blue = 'blue', yellow = 'yellow' } type A = keyof Colors; // number | "toString" | "charAt" | "charCodeAt" | "concat" | ...27 more... | "padEnd"
當把keyof用在string類型的enum上時,咱們就獲得一個由number類型再加上String.prototype上定義的全部的方法的名字組成的一個聯合類型。class