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

TypeScript自定义泛型ToggleStatus赋值与索引报错及泛型失效问题

问题根源与修正方案

原代码的核心问题有两处:

  1. ToggleStatus类型定义中,Extract<T, string>是错误用法——T是StatusProps的子类型(对象类型),要获取它的键名应该用keyof T,而非Extract。
  2. 空对象初始化时无法满足ToggleStatus<T>的完整类型要求;Object.keys返回的是string类型,无法与ToggleStatus<T>的键名类型匹配,导致索引报错。

修正后的完整代码

type StatusProps = {
  [key: string]: React.JSX.Element;
}

// 修正类型定义:用keyof T获取对象键名,生成toggle开头的方法名
type ToggleStatus<T extends StatusProps> = {
  [K in keyof T as `toggle${Capitalize<string & K>}`]: () => void;
}

// 示例:假设props.status的具体类型(替换为你实际的类型)
type DemoStatus = {
  active: React.JSX.Element;
  disabled: React.JSX.Element;
};
const props = { status: {} as DemoStatus };

// 1. 先用Partial允许空对象初始化,逐步填充方法
const toggleStatus: Partial<ToggleStatus<DemoStatus>> = {};

// 2. 将Object.keys返回的key断言为keyof T,让TypeScript识别具体键名
Object.keys(props.status).forEach((key) => {
  const typedKey = key as keyof DemoStatus;
  const methodName = `toggle${Capitalize<string & typedKey>}` as const;
  toggleStatus[methodName] = () => {
    // 这里写入你的业务逻辑
  };
});

// 3. 断言为完整类型(确保循环已覆盖所有键)
const finalToggleStatus = toggleStatus as ToggleStatus<DemoStatus>;

关键修正说明

  • keyof T替代Extract<T, string>:正确获取泛型对象的键名集合。
  • Capitalize<string & K>:过滤掉keyof T可能包含的symbol类型,只处理字符串键名。
  • Partial<ToggleStatus<T>>:允许初始为空对象,避免初始化时的类型不匹配错误。
  • key as keyof T:解决Object.keys返回string导致的索引类型不兼容问题。

更简洁的函数封装方案

如果不想手动处理类型断言,可通过函数封装让TypeScript自动推导类型:

function createToggleStatus<T extends StatusProps>(status: T): ToggleStatus<T> {
  const toggleStatus = {} as ToggleStatus<T>;
  (Object.keys(status) as Array<keyof T>).forEach((key) => {
    const methodName = `toggle${Capitalize<string & key>}` as keyof ToggleStatus<T>;
    toggleStatus[methodName] = () => {
      // 业务逻辑实现
    };
  });
  return toggleStatus;
}

// 使用示例
const toggleStatus = createToggleStatus(props.status);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 11:30:03