JS转TS函数报错:代码路径未返回值与类型索引问题求修复
TypeScript转换后国家数据过滤函数的错误修复
我把一个用于过滤国家数据的JavaScript函数转换为TypeScript后遇到两个错误,无法自行修复,原代码如下:
const countryData = [ { id: 1, name: 'Afghanistan', isoAlpha2: 'AF', isoAlpha3: 'AFG', isoNumeric: 4, currency: { code: 'AFN', name: 'Afghani', symbol: '؋' }, flag: "flasg", callingCodes: ['+93'], languages: ['pus'], emoji: '🇦🇫' }, { id: 2, name: 'Albania', isoAlpha2: 'AL', isoAlpha3: 'ALB', isoNumeric: 8, currency: { code: 'ALL', name: 'Lek', symbol: 'L' }, flag: "flasg", callingCodes: ['+355'], languages: ['sqi'], emoji: '🇦🇱' } ] export interface CountryDataTypes { id: number; name: string; isoAlpha2: string; isoAlpha3: string; isoNumeric: number; currency: { code: string; name: string; symbol: string | boolean; } flag: string; callingCodes: string[]; languages: string[]; emoji: string; } interface Props { name?: string; countryCode?: string; callingCode?: string; currencyName?: string; currencyCode?: string; currencySymbol?: string; isoNumeric?: number; } export function lookup(data: Props): CountryDataTypes { const fields = Object.entries(data) const result = countryData.find((d) => { // Error 1 for (var key in fields) { return d[fields[key][0]] === fields[key][1] //Error 2 } }) return result as CountryDataTypes || {} as CountryDataTypes; }
遇到的错误:
- 错误1:Not all code paths return a value.(并非所有代码路径都返回值)
- 错误2:Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ id: number; name: string; ... }'. No index signature with a parameter of type 'string' was found on type '{ id: number; name: string; ... }'.(元素隐式具有'any'类型,因为字符串类型的表达式无法用于索引指定类型,未找到对应索引签名)
错误修复方案
修复错误1:补全返回逻辑并修正循环逻辑
原find回调函数存在两个问题:一是当fields为空时,循环不执行导致无返回值;二是当前循环会在第一个字段比对后直接返回,无法实现所有传入字段都匹配的过滤需求。需要调整为:遍历所有字段,只要有一个不匹配就返回false,全部匹配完后返回true。
修复错误2:字段映射与类型断言
Props中的字段名和CountryDataTypes的字段名不完全对应(比如countryCode对应isoAlpha2,currencyName对应currency.name),需要先做字段映射,再通过keyof类型断言告诉TypeScript索引的合法性,消除类型报错。
完整修复后的代码
const countryData: CountryDataTypes[] = [ { id: 1, name: 'Afghanistan', isoAlpha2: 'AF', isoAlpha3: 'AFG', isoNumeric: 4, currency: { code: 'AFN', name: 'Afghani', symbol: '؋' }, flag: "flasg", callingCodes: ['+93'], languages: ['pus'], emoji: '🇦🇫' }, { id: 2, name: 'Albania', isoAlpha2: 'AL', isoAlpha3: 'ALB', isoNumeric: 8, currency: { code: 'ALL', name: 'Lek', symbol: 'L' }, flag: "flasg", callingCodes: ['+355'], languages: ['sqi'], emoji: '🇦🇱' } ] export interface CountryDataTypes { id: number; name: string; isoAlpha2: string; isoAlpha3: string; isoNumeric: number; currency: { code: string; name: string; symbol: string | boolean; } flag: string; callingCodes: string[]; languages: string[]; emoji: string; } interface Props { name?: string; countryCode?: string; callingCode?: string; currencyName?: string; currencyCode?: string; currencySymbol?: string; isoNumeric?: number; } export function lookup(data: Props): CountryDataTypes { const fields = Object.entries(data) const result = countryData.find((d) => { for (const [key, value] of fields) { let compareValue: unknown; // 处理字段映射 switch (key) { case 'countryCode': compareValue = d.isoAlpha2; break; case 'callingCode': compareValue = d.callingCodes[0]; break; case 'currencyName': compareValue = d.currency.name; break; case 'currencyCode': compareValue = d.currency.code; break; case 'currencySymbol': compareValue = d.currency.symbol; break; default: compareValue = d[key as keyof CountryDataTypes]; break; } if (compareValue !== value) { return false; } } return true; }) return result ?? ({} as CountryDataTypes); }
内容的提问来源于stack exchange,提问作者Simon Santana
相关产品推荐
相关产品推荐

