簡體   English   中英

提取通用類型的返回類型和 arguments 類型

[英]Extract return type and arguments types of a generic type

為了使它有意義,讓我們看一下這個看起來像 react useReducer 的迷你天真的實現

type Reducer<S, A> = (prevState: S, action: A) => S;
type Dispatch<A> = (value: A) => void;

function useReducer<S, A>(reducer: Reducer<S, A>, initState: S): [getState: () => S, dispatcher: Dispatch<A>] {
  let state = initState;

  return [
    () => state, 
    action => state = reducer(state, action)
  ];
}

// its working as expected (but that is not the question)
type CountActions =
  | { type: "inc" }
  | { type: "dec" }
  | { type: "reset"; payload?: number };

const [getState, dispatch] = useReducer<number, CountActions>(
  (state, action) => {
    if (action.type === "inc") {
      return state + 1;
    }
    if (action.type === "dec") {
      return state - 1;
    }
    if (action.type === "reset") {
      return action?.payload ?? 0;
    }
    return state;
  },
  0
)
getState()//0
dispatch({ type: 'inc' })
dispatch({ type: 'inc' })
getState()//2
dispatch({ type: 'dec' })
getState()//1
dispatch({ type: 'reset', payload: 2 })
getState()//2
dispatch({ type: 'reset' })
getState()//0

我的問題是:有沒有辦法編寫 useReducer 的內部類型,只派生一個條目,即 Reducer 類型?

您將如何編寫ExtractSFromExtractAFrom

// ideally I want to have something that is defined like the real thing ;)

function useReducer<R>(reducer: R, initState: ExtractSFrom<R>): [getState: () => ExtractSFrom<R>, dispatcher: (value: ExtractAFrom<A>) => void] {
  let state = initState;

  return [
    () => state, 
    action => state = reducer(state, action)
  ];
}

提前致謝

這正是infer關鍵字的用途。 如果檢查實際useReducer掛鈎的類型,您會看到 React 正在推斷State的類型和來自 reducer function 的Action

type ReducerState<R extends Reducer<any, any>> = R extends Reducer<infer S, any> ? S : never;
type ReducerAction<R extends Reducer<any, any>> = R extends Reducer<any, infer A> ? A : never;

我們指定泛型R必須是某種縮減器,又名R extends Reducer<any, any> ,然后向后工作以獲取其泛型變量。

useReducer鈎子本身有幾個不同的重載,但基本上它看起來像這樣:

function useReducer<R extends Reducer<any, any>>(
    reducer: R
): [ReducerState<R>, Dispatch<ReducerAction<R>>];

其中泛型是 reducer StateAction的類型是從它派生的。

暫無
暫無

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

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