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
相关产品推荐
相关产品推荐

