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

TypeScript泛型函数返回Formatter<T>类型时索引类型报错求助

解决TypeScript泛型函数Formatter类型索引错误问题

场景重现

定义的类型与工具类型

type Device = {
  manufacturer: string;
  price: number;
  releaseYear: number;
};

type Accessory = {
  color: string;
  size: number;
};

type Formatter<T> = {
  [Key in keyof T as `format${Capitalize<Key & string>}`]: (
    value: T[Key]
  ) => string;
};

报错的泛型函数代码

const getFormatted = <T>(obj: T): Formatter<T> {
  const newObj: Formatter<T> = {};
  Object.keys(obj).forEach((key) => {
      newObj[`format${capitalize(key)}`] = () => obj[key];
  })

  return newObj;
}

const { formatColor, formatSize } = getFormatted<Accessory>({
  color: "#fff",
  size: 2
})

错误信息

Element implicitly has an 'any' type because expression of type '`format${string}`' can't be used to index type 'Formatter<T>'

问题核心

TypeScript无法将format${string}动态字符串与Formatter<T>的键类型建立关联:

  1. Object.keys(obj)返回的是string[],而非精确的keyof T类型
  2. 自定义capitalize函数缺少类型约束,导致生成的键无法被识别为Formatter<T>的合法索引

修正方案

1. 实现类型安全的capitalize函数

先补全运行时的首字母大写逻辑,同时保证类型匹配:

function capitalize(str: string): string {
  return str.charAt(0).toUpperCase() + str.slice(1);
}

2. 修正泛型函数的类型断言与逻辑

const getFormatted = <T extends Record<string, unknown>>(obj: T): Formatter<T> => {
  // 初始空对象断言为Formatter<T>类型
  const newObj = {} as Formatter<T>;

  // 将Object.keys的结果断言为keyof T数组,明确键的类型
  (Object.keys(obj) as (keyof T)[]).forEach((key) => {
    const keyStr = key as string;
    // 生成格式化键并断言为Formatter<T>的合法键
    const formattedKey = `format${capitalize(keyStr)}` as keyof Formatter<T>;
    
    // 赋值格式化函数,确保返回值为string,同时断言类型匹配
    newObj[formattedKey] = (() => {
      const value = obj[key];
      return typeof value === 'string' ? value : String(value);
    }) as Formatter<T>[typeof formattedKey];
  });

  return newObj;
};

3. 测试调用

const { formatColor, formatSize } = getFormatted<Accessory>({
  color: "#fff",
  size: 2
});

console.log(formatColor()); // 输出 "#fff"
console.log(formatSize()); // 输出 "2"

关键说明

  • 用Record<string, unknown>约束泛型T,确保输入对象的键均为字符串类型
  • 通过类型断言将动态生成的键与Formatter<T>的键类型绑定,消除索引错误
  • 格式化函数中统一将值转为字符串,严格匹配Formatter<T>的返回值要求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 02:42:49