Immutable.js 与 React Typescript 结合
Posted
技术标签:
【中文标题】Immutable.js 与 React Typescript 结合【英文标题】:Immutable.js Combine with React Typescript 【发布时间】:2021-07-01 02:47:33 【问题描述】:由于我在项目中使用 Immutable.js,因此我很难将 reducer 重构为 TS 这是我的减速机:
export interface DashboardState
componentId: number | null;
dashboard: number | null;
let defaultState: DashboardState =
componentId: null,
dashboard: null,
;
export default function (state = Map<string, number>(defaultState), action):
Map<string, number>
switch (action.type)
case dashboardsActionsTypes.SET_PROJECT_VIEW:
return state.set('componentId', action.payload);
case dashboardsActionsTypes.SET_DASHBOARD_TYPE:
return state.set('dashboard', action.payload);
default:
return state;
我在 Map(defaultState) 上收到一条错误消息:
我在这里缺少什么?
谢谢
【问题讨论】:
Map
是一个带有 getter 和 setter 等的映射,无论您在其中存储什么数据。我猜你的状态必须是defaultState : Immutable.Map<string, any>
【参考方案1】:
有多种方法可以构造Map
。
export function Map<K, V>(collection: Iterable<[K, V]>): Map<K, V>;
export function Map<V>(obj: [key: string]: V): Map<string, V>;
export function Map<K, V>(): Map<K, V>;
export function Map(): Map<any, any>;
第一次重载的错误是预料之中的,因为你绝对不应该匹配那个。您的对象更接近第二个重载,但您不会自动匹配该重载,因为它涉及 DashboardState
没有的 string
索引签名。
这里快速而肮脏的解决方案涉及在Map
函数上设置一个泛型。如您所见,第二个重载是唯一一个只有<V>
而不是<K, V>
的重载。所以你可以通过为Map
设置一个值类型来匹配这个重载。在这种情况下DashboardState
的值类型是any
。
state = Map<any>(defaultState)
此设置的类型支持非常弱。 state
的键可以是任何string
,值可以是任何东西。如果您无法从中获得任何有用的信息,为什么还要使用 Typescript?
我建议使用官方的Redux Toolkit,它具有强大的打字稿支持以及使用Immer 的不变性支持。并将DashboardState
中的any
替换为实际类型。
编辑:
查看您的编辑后,我建议您使用可选属性 (number | undefined
) 而不是 number | null
,因为 Map.get()
包含 undefined
以及预期值。所以你会得到number | null | undefined
。如果使用可选属性,那么您实际上根本不需要初始状态。您可以使用空的Map
。
我们还可以将键限制为仅DashboardState
的键。
在任何状态类型上使用这些实用程序:
export type MapOf<T> = Map<keyof T, T[keyof T]>;
const createMap = <T,>(): MapOf<T> => Map<keyof T, T[keyof T]>();
对于仪表板:
export interface DashboardState
componentId?: number;
dashboard?: number;
export default function (state = createMap<DashboardState>(), action): MapOf<DashboardState>
switch (action.type)
case dashboardsActionsTypes.SET_PROJECT_VIEW:
return state.set('componentId', action.payload);
case dashboardsActionsTypes.SET_DASHBOARD_TYPE:
return state.set('dashboard', action.payload);
default:
return state;
【讨论】:
Paist 感谢您的解释。我更新了我的代码并将类型添加到默认状态并键入了 Map 构造函数。我不确定我是否理解如何解决这个问题,因为我仍然遇到同样的错误。你能写任何例子,也许我会更好地理解它?export default function (state = Map<number | null>(defaultState), action): Map<string, number | null>
并从 defaultState
中删除类型。但是您应该使用undefined
而不是null
,因为Map.get()
包括undefined
。实际上你应该只使用 Redux Toolkit :)以上是关于Immutable.js 与 React Typescript 结合的主要内容,如果未能解决你的问题,请参考以下文章
将 Flux 存储中的 Immutable.js 映射与内部 React 组件状态合并
在 Immutable.js 中使用 React 的不可变助手