簡體   English   中英

Typescript:通過將 function 參數傳遞給接口來推斷類型

[英]Typescript: Infer type by passing function parameter to a Interface

我有這個界面例如:

interface MyInterface {
    a: Something;
    b: SomethingElse;
}

假設我調用以下內容:

const object: MyInterface = {
    a: {...},
    b: {...},
}
const getValue = (key: keyof MyInterface) => {
    const value: MyInterface[typeof key] = object[key];
    return value;
}

const value = getValue('a');

我最終擁有的是value: Something | SomethingElse value: Something | SomethingElse而不是具有value: Something 當然,這是一個偽示例,實際上我正在從可組合項中的 vuex getter 解析一些數據,但是有人對此有明確的答案嗎? 謝謝你。

我嘗試通過獲取Interface[typeof key]來訪問接口

getValue function 的返回類型被手動設置為MyInterface[typeof key] 但即使沒有這個手動類型,TypeScript 也會將其推斷為typeof object[key] ,即MyInterface[keyof MyInterface] ,這完全相同,因為typeof keykeyof MyInterface

MyInterface[keyof MyInterface]是一個索引訪問類型,它生成索引類型訪問的所有屬性類型的聯合,這里keyof MyInterface 正如 patrickhrastnik 的回答中所述,后者本身就是MyInterface的所有鍵的聯合,即'a' | 'b' 'a' | 'b' 和我MyInterface['a' | 'b'] MyInterface['a' | 'b']Something | SomethingElse Something | SomethingElse

TypeScript 僅執行 static 類型分析,因此這是它可以得出的最好結論,因為它只知道key function 參數類型是keyof MyInterface

因此,為了獲得更窄的返回類型,我們必須限制key的類型。 顯然,我們仍然希望能夠使用 MyInterface 的任何鍵調用getValue MyInterface

一個經典的解決方案利用通用的 function 參數類型推斷讓 TS 猜測調用 functionkey參數的類型; 在那里,它可以將其推斷為更具體的類型,而不是所有keyof union。 我們仍然可以通過適當地約束通用參數類型來接受這些鍵中的任何一個作為可能的參數類型:

const getValue2 = <T extends keyof MyInterface>(key: T) => {
    //^? (key: T) => MyInterface[T]
    const value = object[key];
    return value;
}

通過這個 function 使用 generics,TypeScript 可以為每個調用推斷出更具體的返回類型:

const value2 = getValue2('a');
//    ^? Something

const value2b = getValue2('b');
//    ^? SomethingElse

游樂場鏈接

根據https://www.typescriptlang.org/docs/handbook/2/keyof-types.html

keyof 運算符采用 object 類型並生成其鍵的字符串或數字文字並集。

在此示例中, keyof操作數組合MyInterface的子字段以產生Something | SomethingElse是有意義的。 Something | SomethingElse 據我所知,它是文檔說明操作數的作用。

我沒有使用keyof的經驗,但對我來說,這似乎符合它的設計目的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM