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

