gpt4 book ai didi

typescript - Redux 4.0 中存储增强器的 TypeScript 输入问题

转载 作者:行者123 更新时间:2023-12-04 21:31:19 25 4
gpt4 key购买 nike

一些 TypeScript 大师能帮我弄清楚为什么在 redux 4.0 中创建存储增强器的代码会给我类型错误吗?

最小 repo 是 here .它正在创建一个无所事事的商店 ehnahcer。克隆后,通过运行 yarn 安装依赖项.要查看错误,请运行 yarn run compile .

相关文件是

import {
StoreEnhancer,
StoreEnhancerStoreCreator,
Reducer,
DeepPartial,
AnyAction,
} from 'redux';

interface RootState {
someKey: string;
}

export const enhancer: StoreEnhancer =
(createStore: StoreEnhancerStoreCreator): StoreEnhancerStoreCreator =>
(reducer: Reducer<RootState, AnyAction>, preloadedState?: DeepPartial<RootState>) => {

const store = createStore(reducer, preloadedState);
const newDispatch: typeof store.dispatch = <A extends AnyAction>(action: A) => {
const result = store.dispatch(action);
return result;
}
return {
...store,
dispatch: newDispatch,
};
};


我得到的错误是

src/enhancer.ts(15,5): error TS2322: Type '(reducer: Reducer<RootState, AnyAction>, preloadedState?: DeepPartial<RootState> | undefined) => ...' is not assignable to type 'StoreEnhancerStoreCreator<{}, {}>'.
Types of parameters 'reducer' and 'reducer' are incompatible.
Types of parameters 'state' and 'state' are incompatible.
Type 'RootState | undefined' is not assignable to type 'S | undefined'.
Type 'RootState' is not assignable to type 'S | undefined'.
Type 'RootState' is not assignable to type 'S'.

我不明白为什么 RootState不能分配给 S .

最佳答案

让我们深入了解 StoreEnhancerStoreCreator被定义为

export type StoreEnhancerStoreCreator<Ext = {}, StateExt = {}> = <S = any, A extends Action = AnyAction>(reducer: Reducer<S, A>, preloadedState?: DeepPartial<S>) => Store<S & StateExt, A> & Ext;
这是具有两个类型参数的泛型类型, ExtStateExt .这种类型的结果是另一个泛型函数。例如,如果我们这样做
const genericStoreCreator: StoreEnhancerStoreCreator = <S = any, A extends Action = AnyAction>(r: Reducer<S, A>) => createStore(r)
genericStoreCreator仍将是通用功能。我们已经使用了泛型 StoreEnhancerStoreCreator没有向它提供类型参数(具有默认类型值),但结果仍然是通用函数。
那么我们可以调用 genericStoreCreatorS 提供特定类型参数和 A .
const store = genericStoreCreator((state: RootState = { someKey: 'someKey' }, action: AnyAction) => state)
现在我们有具体的 store没有任何泛型。
您可以考虑 StoreEnhancerStoreCreator作为泛型内部的泛型。
现在让我们回到存储增强器。来自 source (在文档中没有找到)

A store enhancer is a higher-order function that composes a store creator to return a new, enhanced store creator.


所以商店增强器的结果应该仍然是通用商店创建者。在增强器函数内部,我们不应该与特定的状态形状(即它具有 someKey 属性)或特定的 Action 形状(除非它具有 type 属性)相关联。在实现增强器时,我们不知道它将增强哪个确切的商店。
为了使您的代码正常工作,只需在增强器代码中携带泛型
export const enhancer: StoreEnhancer =
(createStore: StoreEnhancerStoreCreator): StoreEnhancerStoreCreator =>
<S = any, A extends Action = AnyAction>(reducer: Reducer<S, A>, preloadedState?: DeepPartial<RootState>) => {

const store = createStore(reducer, preloadedState);
const newDispatch: Dispatch<A> = (action) => {
const result = store.dispatch(action);
return result;
}
return {
...store,
dispatch: newDispatch,
};
};
请注意,增强型商店创建者仍然是通用的,并且可以是具有任何状态和操作的用户。
但是我们可以用增强剂增强什么?如 source says

@template Ext Store extension that is mixed into the Store type.

@template StateExt State extension that is mixed into the state type.


让我们用 print5 扩展存储调用时会将 5 记录到控制台的函数。
export const enhancer: StoreEnhancer<{ print5: () => void }> =
(createStore: StoreEnhancerStoreCreator): StoreEnhancerStoreCreator<{ print5: () => void }> =>
<S = any, A extends Action = AnyAction>(reducer: Reducer<S, A>, preloadedState?: DeepPartial<RootState>) => {

const store = createStore(reducer, preloadedState);
const newDispatch: Dispatch<A> = (action) => {
const result = store.dispatch(action);
return result;
}
return {
...store,
dispatch: newDispatch,
print5 () { console.log(5) },
};
};
再次注意,结果存储仍然是通用的。
这里很简单 demo .记下如何 print5函数从增强器传播到结果存储。

关于typescript - Redux 4.0 中存储增强器的 TypeScript 输入问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50451854/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com