繁体   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