【问题标题】:Immutable.js Combine with React TypescriptImmutable.js 与 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&lt;string, any&gt;

标签: typescript immutable.js react-typescript


【解决方案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 函数上设置一个泛型。如您所见,第二个重载是唯一一个只有&lt;V&gt; 而不是&lt;K, V&gt; 的重载。所以你可以通过为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&lt;number | null&gt;(defaultState), action): Map&lt;string, number | null&gt; 并从 defaultState 中删除类型。但是您应该使用undefined 而不是null,因为Map.get() 包括undefined。实际上你应该只使用 Redux Toolkit :)
猜你喜欢
  • 1970-01-01
  • 2013-02-26
  • 1970-01-01
  • 2020-07-06
  • 2020-10-19
  • 2020-10-24
  • 1970-01-01
  • 2022-12-31
  • 2017-05-21
相关资源
最近更新 更多