如何修复TypeScript中reduce统计字符时的隐式any类型错误
修复TypeScript中Isogram判断函数的类型错误(必须使用reduce实现)
问题描述
需要实现一个判断字符串是否为isogram的函数:字符串包含重复字符返回false,无重复字符返回true。现有功能正常的代码,但TypeScript解析器抛出类型错误,要求修复且必须保留reduce()的使用。
原始代码:
function isIsogram(str: string): boolean { const lower = str.toLocaleLowerCase(); let db: Record<string, number> = {}; db = lower.split('').reduce((acc, item) => { if (item in acc) { acc[item]++; // error: Element implicitly has an 'any' } else { acc[item] = 1; // error: Element implicitly has an 'any' } return acc; }, {}); return Object.values(db).every((i) => i === 1); } console.log(isIsogram('')); // true console.log(isIsogram('Dermatoglyphics')); // true console.log(isIsogram('isogram')); // true console.log(isIsogram('aba')); // false console.log(isIsogram('moOse')); // false console.log(isIsogram('isIsogram')); // false
错误信息(中文翻译)
元素隐式拥有 "any" 类型,因为类型为 "string" 的表达式不能用于索引类型 "{}"。在类型 "{}" 上找不到参数类型为 "string" 的索引签名。(7053)
错误原因
reduce()的初始值{}被TypeScript推断为{}类型,该类型没有定义字符串索引签名,因此访问acc[item]时TS无法确定值的类型,抛出隐式any错误。虽然最终结果会赋值给Record<string, number>类型的变量,但reduce内部的累加器acc类型并未被正确推导。
修复方案
给reduce()的初始值指定明确的类型,有两种常用方式:
方式1:类型断言初始值
将初始值{}断言为Record<string, number>类型,明确累加器的结构:
function isIsogram(str: string): boolean { const lower = str.toLocaleLowerCase(); const db = lower.split('').reduce((acc, item) => { if (item in acc) { acc[item]++; } else { acc[item] = 1; } return acc; }, {} as Record<string, number>); return Object.values(db).every(count => count === 1); }
方式2:指定reduce泛型参数
直接给reduce指定泛型参数,明确累加器的类型:
function isIsogram(str: string): boolean { const lower = str.toLocaleLowerCase(); const db = lower.split('').reduce<Record<string, number>>((acc, item) => { if (item in acc) { acc[item]++; } else { acc[item] = 1; } return acc; }, {}); return Object.values(db).every(count => count === 1); }
两种方式都能让TypeScript正确识别累加器acc的类型,消除隐式any错误,同时保留原有的功能逻辑。
内容的提问来源于stack exchange,提问作者Sergey
相关产品推荐
相关产品推荐

