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

TypeScript泛型数组入参时函数返回类型错误的修正方案

TypeScript字节转换函数类型错误分析与修复

问题原因

原函数将泛型TSize约束为数组类型('kilobyte' | 'megabyte')[],当使用keyof TSize时,TypeScript会将其解析为数组的索引键(比如"0"、"1"),而非数组元素对应的单位字符串。因此返回类型Record<keyof TSize, number>会被推断为Record<"0", number>这类以索引为键的对象,导致调用时访问megabyte属性触发TS2339错误。

修复方案

调整泛型约束逻辑:让TSize直接代表需要转换的单位联合类型,而非数组类型;将get参数指定为TSize[],返回类型改为Record<TSize, number>,确保返回对象的键与传入的单位字符串完全匹配。

修正后的代码

export function formatFromBytes<TSize extends 'kilobyte' | 'megabyte'>(
  bytes: number,
  get: TSize[],
  useDecimal = false,
): Record<TSize, number> {
  const marker = useDecimal ? 1000 : 1024;
  const decimal = 0;

  return get.reduce((acc, cv) => {
    switch (cv) {
      case 'kilobyte':
        acc[cv] = +(bytes / marker).toFixed(decimal);
        break;
      case 'megabyte':
        const megaBytes = marker * marker;
        acc[cv] = +(bytes / megaBytes).toFixed(decimal);
        break;
      default:
        // 类型兜底,确保所有单位分支都被覆盖
        const _exhaustiveCheck: never = cv;
        throw new Error(`Unexpected size type: ${_exhaustiveCheck}`);
    }
    return acc;
  }, {} as Record<TSize, number>);
}

验证调用示例

// 单单位调用,类型推断正确,无TS错误
const singleUnitResult = formatFromBytes(5000000, ['megabyte']);
console.log(singleUnitResult.megabyte);

// 多单位调用,所有属性均可正常访问
const multiUnitResult = formatFromBytes(5000000, ['kilobyte', 'megabyte']);
console.log(multiUnitResult.kilobyte, multiUnitResult.megabyte);

内容的提问来源于stack exchange,提问作者Md. A. Apu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 17:05:11