You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React+Redux+TypeScript中,如何定义mapKeys转换后的对象接口?

好的,针对你在React+Redux项目中用Lodash的mapKeys把ITodo数组转成扁平化对象的场景,我来帮你定义对应的TypeScript接口/类型,其实有两种简洁的方式可以实现:

方案1:自定义带索引签名的接口

因为mapKeys转换后的对象,键是字符串类型的id(注意:JavaScript对象的键会自动把数字转为字符串,比如原id:1会变成键"1"),所以我们可以用TypeScript的索引签名来定义这个对象的类型:

import { ITodo } from './your-path-to-ITodo';

interface ITodoMap {
  // 用字符串类型作为键,对应的值是ITodo类型
  [todoId: string]: ITodo;
}

方案2:使用TypeScript内置的Record工具类型

TypeScript提供了内置的Record<K, T>工具类型,专门用来表示“键类型为K,值类型为T”的对象,用它来定义会更简洁:

import { ITodo } from './your-path-to-ITodo';

// Record<键类型, 值类型>
type ITodoMap = Record<string, ITodo>;

额外说明:为什么键是string而不是number?

虽然你的ITodo接口中id是number类型,但在JavaScript中,对象的属性名(键)只能是string或symbol——哪怕你传入数字作为键,JS也会自动把它转为字符串。比如_.mapKeys(response, 'id')生成的对象,键实际是"1"、"2"这类字符串,而非数字1、2,所以TypeScript的类型必须匹配这个实际运行时的结构,否则会出现类型不兼容的问题。

在Reducer中的使用示例

定义好类型后,你可以在Redux reducer中这样使用:

import _ from 'lodash';
import { ITodo, ITodoMap } from './your-types-path';

// 假设你的state类型
interface TodoState {
  todos: ITodoMap;
  // 其他状态字段...
}

const initialState: TodoState = {
  todos: {},
  // 其他初始值...
};

const todoReducer = (state = initialState, action: any) => {
  switch (action.type) {
    case 'FETCH_TODOS_SUCCESS':
      // 这里可以用泛型参数指定类型,避免类型断言
      const todosMap = _.mapKeys<ITodo, string>(action.payload, 'id');
      return {
        ...state,
        todos: todosMap,
      };
    // 其他case...
    default:
      return state;
  }
};

如果不想用泛型参数,也可以用类型断言:_.mapKeys(action.payload, 'id') as ITodoMap,效果是一样的。

内容的提问来源于stack exchange,提问作者Keslavi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:35:42