理解TypeScript中的一個(gè)(偽)黑魔法

理解TypeScript中的一個(gè)(偽)黑魔法

最近在學(xué)習(xí)TypeScript的時(shí)候,看到高級(jí)類型這里,對(duì)

function pluck<T, K extends keyof T>(o: T, names: K[]): T[K][] {
    return names.map(n => o[n]);
}

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

let person: Person = {
    name: 'Jarid',
    age: 35
};

let strings: string[] = pluck(person, ['name']); 

這段代碼有點(diǎn)不太理解,感覺像是黑魔法一般咒唆,主要的疑惑點(diǎn)在于:

let strings: string[] = pluck(person, ['name']);

這段代碼,傳入給pluck的應(yīng)該是一個(gè)string[]内颗,那么泛型函數(shù)

function pluck<T, K extends keyof T>(o: T, names: K[]): TK;

這個(gè)簽名應(yīng)該被替換為钧排,

function pluck<Person, string extends keyof Person>(o: Person, names: string[]): Person[string][];

其中

keyof Person

等價(jià)于

'name' | 'age'

于是對(duì)于約束:

string extends 'name' | 'age'

而言,就是絕對(duì)通不過靜態(tài)類型檢查的均澳,但是在這里卻是能夠通過的恨溜,這讓我百思不得其解符衔。

后來我懷疑自己看漏了什么重要的東西,于是把文檔往上翻糟袁,在字符串字面量類型這里判族,看到了一點(diǎn)端倪,于是我在TypeScript中做了這樣子的嘗試:

type MyType = 'myType';
function bar(param : MyType[]) : void {
    console.log(param);
}
bar(['myType']);

結(jié)果是輸出了:

["myType"]

于是我恍然大悟项戴,在前面的代碼中TypeScript的類型約束事實(shí)上是做了這樣子的工作:

  1. 通過

    keyof Person
    

    獲得了

    "name" | "age"
    
  2. 根據(jù)

    K extends keyof Person
    

    約束了K要么是“name”要么是“age”**

    假設(shè)如果兩者都不是形帮,那么靜態(tài)檢查將會(huì)直接報(bào)錯(cuò);

  3. 現(xiàn)在靜態(tài)檢查器來檢查

    names : K[]
    

    由于傳入的是['name']周叮,那么首先如果將其解釋為string[]的話顯然是不對(duì)的辩撑,那么進(jìn)一步地,TypeScript靜態(tài)檢查器嘗試將['name']中的'name'看成是一個(gè)字符字面量類型仿耽,然后將其解釋為'name'[]合冀,即字符字面量類型數(shù)組,這樣一來项贺,泛型變量K就是'name'君躺,約束'name' extends 'name' | 'age'就順利通過了。**

  4. 進(jìn)一步的开缎,T[K]事實(shí)上就是Person['name']棕叫,而Person['name']就是string所以這個(gè)函數(shù)的返回值就是string[]

為了驗(yàn)證我的猜想奕删,我把最后那行調(diào)用改成了

let strings: string[] = pluck(person, ['name', 'name', 'name']); 

然后測試的時(shí)候輸出:

["Jarid", "Jarid", "Jarid"]

這符合我的理解俺泣。

總結(jié)一下,其實(shí)理解這個(gè)問題最大的關(guān)鍵就是理解TypeScript字符串字面量類型這個(gè)概念急侥,這個(gè)概念使得TypeScript的靜態(tài)檢查變得相當(dāng)靈活砌滞,從上面的描述我們可以看出'name'這個(gè)字符串使得TypeScript靜態(tài)分析的時(shí)候做了一定的推斷(可能推斷過程和我的描述并非一致侮邀,因?yàn)槲疫€沒有仔細(xì)研讀過TypeScript的源代碼)坏怪,這使得我們在閱讀TypeScript源代碼的時(shí)候需要額外地注意這樣一些靈活之處。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末绊茧,一起剝皮案震驚了整個(gè)濱河市铝宵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌华畏,老刑警劉巖鹏秋,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異亡笑,居然都是意外死亡侣夷,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門仑乌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來百拓,“玉大人琴锭,你說我怎么就攤上這事⊙么” “怎么了决帖?”我有些...
    開封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蓖捶。 經(jīng)常有香客問我地回,道長,這世上最難降的妖魔是什么俊鱼? 我笑而不...
    開封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任刻像,我火速辦了婚禮,結(jié)果婚禮上并闲,老公的妹妹穿的比我還像新娘绎速。我一直安慰自己,他們只是感情好焙蚓,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開白布纹冤。 她就那樣靜靜地躺著,像睡著了一般购公。 火紅的嫁衣襯著肌膚如雪萌京。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天宏浩,我揣著相機(jī)與錄音知残,去河邊找鬼。 笑死比庄,一個(gè)胖子當(dāng)著我的面吹牛求妹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播佳窑,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼制恍,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了神凑?” 一聲冷哼從身側(cè)響起净神,我...
    開封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎溉委,沒想到半個(gè)月后鹃唯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瓣喊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年坡慌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片藻三。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡洪橘,死狀恐怖絮爷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情梨树,我是刑警寧澤坑夯,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站抡四,受9級(jí)特大地震影響柜蜈,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜指巡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一淑履、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧藻雪,春花似錦秘噪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至便斥,卻和暖如春至壤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背枢纠。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來泰國打工像街, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人晋渺。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓镰绎,卻偏偏與公主長得像,于是被迫代替她去往敵國和親木西。 傳聞我的和親對(duì)象是個(gè)殘疾皇子畴栖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法户魏,內(nèi)部類的語法驶臊,繼承相關(guān)的語法,異常的語法叼丑,線程的語...
    子非魚_t_閱讀 31,639評(píng)論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)扛门,斷路器鸠信,智...
    卡卡羅2017閱讀 134,664評(píng)論 18 139
  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young閱讀 3,814評(píng)論 1 10
  • 從臘月底到正月初,我有兩位同學(xué)結(jié)婚论寨。大喜的日子正好趕在假期星立,難得爽茴,聚少離多的同學(xué)們從祖國各地前來道喜,可喜可賀绰垂,我...
    小馬哥的寫生簿閱讀 358評(píng)論 0 0
  • 兒子這個(gè)月剛滿兩歲室奏,最近兩天發(fā)現(xiàn)他的自尊心變得好大!不能受氣劲装!不能說胧沫!甚至大聲一點(diǎn)點(diǎn)的斥責(zé),他立刻委屈給你看…… ...
    昨天之前明天以后閱讀 209評(píng)論 0 0