我目前正在尝试编写一个类型化的 React 钩子,但在这样做时遇到了麻烦。我的函数如下所示:
export const useProjectState = <
GetStateArgs extends any[],
StateShape,
Dispatcher
>(
state: State<GetStateArgs, StateShape, Dispatcher>,
...args: GetStateArgs
): [StateShape, Dispatcher] => {
const [currentState, setCurrentState] = useState<StateShape>(() =>
state.getState(...args)
);
useEffect(() => {
const update = () => setCurrentState(state.getState(...args));
state.subscribe(update);
return () => state.unsubscribe(update);
}, [state]);
return [currentState, state.dispatchers];
};
虽然我使用它时,保留了泛型的形状,但不保留它们的类型:
{ name, author }
是推断的,但不是 { name: string, author: string }
例如。我也尝试从 State 类型中提取泛型:
const useProjectState = <
CurrentState extends State<any[], any, any>
>(
state: CurrentState,
...args: CurrentState extends State<infer GetStateArgs, any, any> ? GetStateArgs : never
): [
CurrentState extends State<any[], infer StateShape, any> ? StateShape : never,
CurrentState extends State<any[], any, infer Dispatchers> ? Dispatchers : never
] => {
但是这样不行,类型都变成了unknown
:
我似乎找不到任何方法让它起作用,有人可能知道我做错了什么或让它起作用的方法吗?
这就是 State
的样子:
export interface State<
GetStateArgs extends any[],
StateShape,
Dispatchers
> {
subscribe: (fn: () => void) => void;
unsubscribe: (fn: () => void) => void;
getState: (...args: GetStateArgs) => StateShape;
forceUpdate: () => void;
dispatchers: Dispatchers;
}