亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

打字稿:正確推斷包裝函數的參數和返回類型

打字稿:正確推斷包裝函數的參數和返回類型

交互式愛情 2023-05-18 10:29:10
我正在嘗試創建一個包裝函數,它接受一個查詢和一個化簡器,然后返回本質上相同的函數,但有一個附加屬性 ( ) 包含_data查詢數據的處理版本(具體來說,我想轉換查詢結果到Immutable.js記錄)。我希望此函數對任何可能的查詢都是通用的,并保留查詢中的調用簽名和類型信息。我試圖通過使用Parameters<typeof queryHook>和來做到這一點ReturnType<typeof queryHook>。但是,當我將參數傳遞給queryHook內部函數時,Typescript 抱怨說參數不能分配給內部函數,即使它們應該從該函數的參數中鍵入。我的問題是,為什么 Typescript 不能告訴傳遞給包裝查詢的參數應該與查詢的預期參數具有相同的類型?目前,它給出了一個錯誤,表明可能queryHook是任何可能的查詢,而不是傳遞給函數的特定查詢。奇怪的是,如果我真的使用這個函數,所有類型都會被正確推斷出來&hellip;&hellip;我的代碼如下:/** List of all possible hooks to wrap */type AllQueryHooks = typeof useGetPaymentsQuery | typeof useGetAddressesQuery/**?* @param queryHook GraphQL query to wrap?* @param reducer Function to transform GraphQL result. Return value will be?*? ? ?available on the _data prop?*/export function wrapGQLHook<T, Hook extends AllQueryHooks>(? queryHook: Hook,? reducer: (data: ReturnType<typeof queryHook>['data']) => T,): (? ...args: Parameters<typeof queryHook>) => ReturnType<typeof queryHook> & { _data: T | undefined } {? function wrappedGQLHook(...args: Parameters<typeof queryHook>) {? ? const queryResult = queryHook(...args)? ? // ...args is overloaded? ? ? ^^^^^^^? ? let _data: T | undefined = undefined? ? if (queryResult.data) {? ? ? _data = reducer(queryResult.data)? ? }? ? return { ...queryResult, _data }? }? return wrappedGQLHook? //? ? ?^^^^^^^^^^^^^^ not assignable to ReturnType<Hook>}/**?* Wrapped useGetPaymentsQuery hook?*?* Returns useGetPaymentsQuery vars, plus a _data prop containing a List of?* PaymentRecords?*/export const useGetPaymentsQueryWrapped = wrapGQLHook(? useGetPaymentsQuery,? (data) => {? ? if (!data) return? ? const { Payments } = data? ? return Payments.edges.map((node) => node)? ? // ^^^^^^^^^^^^? ?return type inferred correctly &macr;\_(ツ)_/&macr;? },)
查看完整描述

1 回答

?
慕仙森

TA貢獻1827條經驗 獲得超8個贊

與其嘗試基于兩個特定鉤子的簽名向后工作,不如嘗試創建一個更通用的函數。Typescript 應該能夠根據您作為參數傳入的掛鉤來推斷特定類型。

從思考我們知道什么和不知道什么開始。我們不知道的東西變成了泛型。

  • 鉤子是一個帶有一些參數(A)的函數??梢杂腥我鈹盗康娜我忸愋偷膮?( A extends any[])。

  • 它返回一些對象 ( R),該對象可能具有名為“數據”的屬性 ( R extends { data?: any })。

  • reducer 是一個函數,它獲取鉤子 ( R['data']) 返回的數據并將其映射到某個新值 ( M)。

  • 修改后的鉤子采用相同的參數 ( A) 并返回一個對象,其中包含鉤子的所有返回值 ( R) 和一個附加屬性“_data”,其值從 reducer 返回 ( M) 或可能未定義 ( R & { _data: M | undefined })。

把所有這些放在一起,我們得到這個:

export function wrapGQLHook<A extends any[], R extends { data?: any }, M>(

    queryHook: (...args: A) => R,

    reducer: (data: R['data']) => M,

) {

    return (...args: A): R & { _data: M | undefined } => {

        const queryResult = queryHook(...args)

        let _data: M | undefined = undefined

        if (queryResult.data) {

            _data = reducer(queryResult.data)

        }

        return { ...queryResult, _data }

    }

}

這似乎對我有用,但在不知道鉤子簽名的情況下我無法非常徹底地測試它。

游樂場鏈接


查看完整回答
反對 回復 2023-05-18
  • 1 回答
  • 0 關注
  • 115 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號