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

如何为对象fastMap添加泛型类型以实现正确类型推导?

解决方案

核心问题是fastMap初始类型为{},TypeScript无法跟踪动态添加的条目类型,我们可以通过明确类型定义、泛型约束来解决这个问题:

1. 定义基础类型

先抽离单个条目的类型,确保每个属性的类型都清晰:

import { atom } from 'jotai'; // 假设你使用Jotai的atom,按需调整
import { PayloadAction } from '@reduxjs/toolkit';

// 确保你的RootState和SliceState已提前定义
type RootState = { /* 你的RootState结构 */ };
type SliceState = { /* 你的SliceState结构 */ };

// 单个FastMap条目的类型
type FastMapEntry<S, T> = {
  value: T;
  selector: (state: RootState) => T;
  atom: ReturnType<typeof atom<T>>; // 明确atom存储T类型的值
  dispatch: (state: S, action: PayloadAction<any>) => void;
};

// FastMap的基础索引类型
type FastMap = Record<string, FastMapEntry<any, any>>;

2. 初始化fastMap并约束addToFastMap泛型

修改addToFastMap,把key也作为泛型参数,同时在赋值时断言条目类型,还可以返回一个带类型的getter避免直接访问的类型模糊:

export const fastMap = {} as FastMap;

export type FastMapOptions<K extends string, S, T> = {
  key: K;
  value: T;
  selector: (state: RootState) => T;
  dispatch: (state: S, action: PayloadAction<any>) => void;
};

export const addToFastMap = <K extends string, S, T>(options: FastMapOptions<K, S, T>) => {
  const { key, value, selector, dispatch } = options;
  // 创建明确类型的atom
  const entryAtom = atom<T>({ key, default: value });

  // 将条目断言为对应类型后存入fastMap
  fastMap[key] = {
    value,
    selector,
    atom: entryAtom,
    dispatch
  } as FastMapEntry<S, T>;

  // 返回带类型的getter函数,直接获取条目时自动匹配类型
  return () => fastMap[key] as FastMapEntry<S, T>;
};

3. 使用示例

调用addToFastMap时,泛型会自动推断(也可手动指定),通过返回的getter获取条目时能自动获得正确类型:

// 调用时自动推断泛型,或手动指定<"margin", SliceState, number>
const getMarginEntry = addToFastMap({
  key: "margin",
  value: 20,
  selector: (state: RootState) => state.properties.margin,
  dispatch: marginUpdatedReducer
});

// 获取条目,TypeScript自动识别value为number类型
const marginEntry = getMarginEntry();
console.log(marginEntry.value); // 类型为number
marginEntry.dispatch(/* 参数自动匹配SliceState和PayloadAction类型 */);

4. 预先定义所有key的类型(可选)

如果所有key都是已知的,可以预先定义FastMap的完整类型,这样直接访问fastMap[key]也能获得类型提示:

// 预先定义所有key对应的条目类型
type FastMapFinal = {
  margin: FastMapEntry<SliceState, number>;
  padding: FastMapEntry<SliceState, number>;
  // 其他key...
};

// 初始化时断言为完整类型
export const fastMap = {} as FastMapFinal;

// 调用addToFastMap时,TypeScript会检查key是否符合定义
addToFastMap({
  key: "margin", // 合法,匹配类型定义
  value: 20,
  selector: (state: RootState) => state.properties.margin,
  dispatch: marginUpdatedReducer
});

// 直接访问时自动识别类型
const marginValue = fastMap.margin.value; // 类型为number

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 09:26:16