TypeScript中API返回unknown类型对象的类型定义与遍历报错问题
问题解决与写法合规性说明
报错原因
TypeScript报错的核心是**fetch返回的JSON数据默认是unknown类型**,你直接把Object.values(data.races)的遍历值指定为RaceInfo,但TypeScript无法确认data.races的结构确实符合预期的键值对格式,因此判定类型不兼容。
解决forEach报错的方案
步骤1:定义完整的API响应类型
先给接口返回的整个数据结构声明类型,明确races是“字符串键 + RaceInfo值”的对象:
interface ApiResponse { success: boolean; races: Record<string, RaceInfo>; }
步骤2:给JSON数据指定类型
通过类型断言或类型守卫,让TypeScript识别API返回数据的结构:
方式一:类型断言(简单直接)
export default async function getSC(selection: Selection) { let sc: string | undefined; // 给sc声明明确类型,避免隐式any await fetch(`URL`, { method: "GET" }) .then((response) => response.json() as ApiResponse) // 断言为ApiResponse类型 .then((data) => { if (data.success) { // 此时Object.values(data.races)自动推导为RaceInfo[] Object.values(data.races).forEach((value) => { if ( value.codes.race_sc.slice(-4) === selection.time && value.details.venue === selection.venue ) { sc = value.codes.race_sc; } }); } else { console.log("Could not fetch the races"); } }) .catch((error) => { console.log("Error:", error); }); return sc; }
方式二:类型守卫(更严谨,适合不确定API返回结构的场景)
// 定义类型守卫函数,验证数据是否符合ApiResponse结构 function isApiResponse(data: unknown): data is ApiResponse { return ( typeof data === 'object' && data !== null && 'success' in data && typeof (data as ApiResponse).success === 'boolean' && 'races' in data && typeof (data as ApiResponse).races === 'object' && (data as ApiResponse).races !== null ); } export default async function getSC(selection: Selection) { let sc: string | undefined; await fetch(`URL`, { method: "GET" }) .then((response) => response.json()) .then((data) => { if (isApiResponse(data) && data.success) { // 这里data.races会被正确推导为Record<string, RaceInfo> Object.values(data.races).forEach((value) => { if ( value.codes.race_sc.slice(-4) === selection.time && value.details.venue === selection.venue ) { sc = value.codes.race_sc; } }); } else { console.log("Could not fetch the races"); } }) .catch((error) => { console.log("Error:", error); }); return sc; }
for...of写法的合规性说明
你当前的for...of写法不符合严格TypeScript规范,原因如下:
data.races是unknown类型,Object.keys(data.races)返回的string[]无法直接关联到data.races的键类型,直接访问value.codes会在严格模式下触发类型报错(你当前可能关闭了严格检查所以未报错)。- 变量
sc未声明类型,会被隐式推导为any,违背TypeScript的类型安全原则。
修正后的合规for...of写法
结合前面定义的ApiResponse类型,修正后写法如下:
export default async function getSC(selection: Selection) { let sc: string | undefined; await fetch(`URL`, { method: "GET" }) .then((response) => response.json() as ApiResponse) .then((data) => { if (data.success) { for (const key of Object.keys(data.races)) { const value = data.races[key]; // 自动推导为RaceInfo类型 if ( value.codes.race_sc.slice(-4) === selection.time && value.details.venue === selection.venue ) { sc = value.codes.race_sc; } } } else { console.log("Could not fetch the races"); } }) .catch((error) => { console.log("Error:", error); }); return sc; }
内容的提问来源于stack exchange,提问作者Karolis K
相关产品推荐
相关产品推荐

